Struggling to get Belongs_to and Has_many associations to work in Phoenix project

Hi,

I’m new to Elixir and Phoenix and struggling immensely to get Belongs_To and Has_many to work in a Phoenix project. I’ve gone through several guides that are something along the lines of connecting User_ID to Posts or Post_ID to Comments but none of them work as I’m assuming they are outdated (or I’m just bad at following simple instructions). I’m not familiar enough with Elixir or Phoenix to figure this out myself so was hoping someone might be able to just show me a template of what I should be expecting to see that I can work from.

So far I’ve just run Mix.Gen.Auth and Mix.Gen.Html to produce the following

  schema "users" do
    field :email, :string
    field :password, :string, virtual: true, redact: true
    field :hashed_password, :string, redact: true
    field :confirmed_at, :naive_datetime
    has_many :posts, Z.A.Posts
  schema "posts" do
    field :name, :string
    belongs_to :user, Z.Accounts.User

At this point if I start the server and make a post, then check Postgres I can see the ID and Name field get updated, and the User_ID field remains blank. So everything looks fine up to this point

The issue I’ve got is my lack of understanding of Elixir, and trying to learn it from several different tutorials that seem to all have a completely different approach on how to assign the User_ID to the new Post.

Is there a standard way in which I can assign the ID from one schema to another’s ID basically? Linking Users to Posts or Posts to Comments type of thing. I’m getting so confused as I’ve seen tutorials using cast_assoc, build_assoc, some of them change the Changeset within the ‘posts’ schema whilst others seem to do do everything from the PostController. Most examples I see only show one part of the entire process as well, so I’m very lost on how to do this, and can’t find a single tutorial that actually works from start to finish. Its difficult for me to try and splice different ones together to get something that actually works as most of them are 2-8 years old and have completely different approaches to doing the same thing, so there’s obviously things that used to work that got changed over time.

I just want a very basic example of something that works so I can learn from it.

1 Like

It’s ```, not ‘’’ to wrap code… I made the change to your post.

The simplest way is to cast user_id… but I prefer the long way.

I modify context function to add create_post/2 and pass the user.

Then I use build_assoc to create the initial post with user_id already set.

Sometime I simply cast foreign id, in particular when a resource belongs_to many things.

But for ownership, I pass the user when creating the resource.

Something like this… (not tested)

def create_post(%User{} = user, attrs) do
  user
  |> Ecto.build_assoc(:posts)
  |> Post.changeset(attrs)
  |> Repo.insert()
end
1 Like

Thanks for trying to help, but I think I’m gonna give up on Elixir though to be honest and just learn Ruby/Rails instead lol. Been trying to figure this out for days and it’s just too hard for a new person when all the advice/guides you get only include half the information and assume you will just know the rest.

You should have started with the official documentation

https://hexdocs.pm/ecto/Ecto.html#content

Always up to date…

2 Likes

My issue isn’t following abstract parts of the whole process, it’s understanding the whole process. The Hexdocs are great at telling you what to do in specific files or how specific things work, but they don’t tell you how those files are connected within Phoenix for what I am asking.

I made my post because I’ve seen lots of ‘guides’ or examples with the type of information you provided in your first response but this is only useful if I know how to do the other things you mentioned and how everything connects. I was asking for a full working example, not more vague stuff I could already find. The Hexdocs information on this is the equivalent of teaching someone to change a tyre by showing them how to pull the tyre off once the cars already been jacked up and had the nuts removed. If someone doesn’t know how to do the other stages, the information is useless.

You can check this one out: GitHub - tamanugi/realworld-phoenix: Exemplary real world application built with Elixir+Phoenix https://realworld.io

It’s part of the much bigger RealWorldProject implemented in many languages and frameworks.

5 Likes

If this was true, how are so many people using Phoenix and Ecto? Everyone who started using it was new at some point.

This is not true, in my experience. At most they expect you to have some familiarity with the underlying concept. i.e. if you are using Ecto you will need to know how to do what you want in SQL and the docs will help you translate it into Ecto magic. If you are using Phoenix you need to know about different web concepts and might need to peruse the Ecto documentation for more details on how the database integrations work. This seems fair to me.

To me it sounds like you might be missing some fundamental knowledge and are getting frustrated. If you really wanted to stick with Phoenix + Ecto you would be able to get very good advice on this forum. But you need to do a couple things differently.

First, your questions need to be more focused . It’s almost impossible to know where your issue is in your original post. Make it more concise so that there is something to reply to. Break it up into several concise questions if you have to.

Second, your responses sound like you’re not interested in getting advice or getting past this hurdle. I would personally be insulted if I was kokogorille. All you did was complain at them when they took time out of their day to try to help you.

4 Likes
  1. Sorry, but with such attitude changing language would not help you. Changing language because you did not liked one forum response does not looks promising regardless of context.

  2. Look that for others it does not matter if you spend few days or weeks. You have posted today and already received reply. We can’t travel in time and help you in all of those days before you have posted.

  3. Rushing with a first project without understanding how things you use works is not the best idea. You should learn it first and ask questions if you don’t understand something. You can try to search for learning resources by yourself for example in #learning-resources category and as always you are welcome to ask for a help for finding a best resource for you.

  4. @kokolegorille didn’t give you half of the information. It’s an answer full of keywords. He described two ways how to do it. Look that copy-paste whole ecto documentation isn’t also something you want, right? The hexdocs documentation have a search field. If you type for example cast even without pressing you would instantly get an option to navigate to Ecto.Changeset.cast/4 function. The second way have even link to build_assoc documentation.

  5. Giving just a hint instead of providing a complete working example is a good practice. When I’m sending an example code I’m also adding lots of comments and I’m linking a helpful resources, so others may learn more than what I wrote. Simply you would not learn much from copy-paste.

  6. No matter if you are on Elixir, Ruby on any other forum nobody is obligated to do a work for you. The primary thing is to educate by providing a generic answers, so many readers may found our answers helpful.


Besides above let’s focus on your problem … Correct me if I’m wrong, but most probably you started learning full phoenix environment without touching ecto first? Look that you can use phoenix to work with other libraries as well as even without ecto, so it simply does not makes sense to learn ecto from phoenix documentation, right?

So it should be obvious to look for ecto associations guide to understand how ecto and associations works. I would start with those guides:
https://hexdocs.pm/ecto/getting-started.html
https://hexdocs.pm/ecto/constraints-and-upserts.html
https://elixirschool.com/en/lessons/ecto/associations

Have in mind that simply some things changed. For example in elixircasts video they are using old templates with <%= form for=… %> call instead of heex templates which are relatively new features, but it should not cause any problem especially if you test your code in iex shell.

Also you may find this interesting:

In very different example I show how to setup ecto-only environment in one Elixir script file. If you did not know what it is then just give it a try simply by writing such example to file and calling it using following command elixir example.exs in your shell. :smiling_imp:

Let us know if you don’t understand something…

3 Likes

You can say I have a bad attitude, but I can say the same for yourself and the person that I was replying to. It’s not helpful to give a response that doesn’t help someone, its just typing for the sake of it. My original post states multiple times my issue is that I am getting confused with how Elixir/Phoenix works due to reading multiple guides covering the same thing spanning 2-8 years which all do everything differently. Giving me a line of code or telling me ‘just do it’ is not even remotely helpful for what I am asking as my problem is understanding the overall process and not the individual lines of code that I can easily find on Hexdocs myself.

I even mentioned in my post that I’ve seen tutorials using build_assoc but there’s not enough information for me to get it to work as I don’t know what else I’m meant to be doing. I’m asking how do I get associations to work in Phoenix, not which lines of code have something remotely to do with associations.

There have been things I’ve spent the time to figure out on my own on Elixir that I could have probably asked about and got solved in minutes instead of days already, I only asked because I was desperate. I’ve read through the forums for other issues so I knew it would be a very long shot to find someone that could actually help me.

You linked me a bunch of guides that I’ve already tried to use and don’t work by the way lol. They are the reason I made this post to begin with. There’s information missing or outdated in each one, which is the entire reason I was asking for help to start with.

Also, it took me less than an hour to figure it out on Ruby. Problems not the mentality, its how outdated and unhelpful the resources are to do with the language. I liked Elixir, but trying to learn it compared to other languages just feels like masochism.

Yeah…never gonna ask for anything again lol

I think that you are just tired because you missed something small and most probably after fixing that your code could work. Sometimes advice to give a break and chill is best even if it has nothing to do with code. Happens to senior developers as well - no need to worry.

As it was said before everyone here from the very start was using exactly same tutorials and all you say is that you don’t understand them. How would you reply if I say that I don’t understand String methods in Ruby?

Once again, what exactly you don’t understand.

Oh, only an hour? I guess that there is someone who can make it work in Assembler in just 30 minutes. Ruby is terrible and everyone should use Asembler! Do you really like such replies?

hexdocs documentation is up to date step by step guide. Maybe you just don’t understand the functional programming? Again “maybe” as I can only guess. I don’t see what have you tried. If you mention Ruby then there is a change you are trying to write code like in OOP languages.

number = 5
if some_condition_goes_here do
  number = 7
end
# number here is 5

But if you do not build assoc inside if/case/cond condition like above the example reply does not makes sense. If guides does not help then we need to see your code to show exactly which line in your code is wrong.

Maybe better try to be on our side for few minutes and try to answer why some String methods in Ruby are not working as expected. Don’t ask me which functions I mean and don’t even dare to ask for a code example. I have read Ruby documentation and it still does not work for me. Please solve my problem. If you replace Ruby with Elixir and String methods with Ecto.Schema the question is exactly same.

Also I have just noticed one thing:

What is it? It looks like you have really bad habits/practices. If you use one letter aliases or variables so often in whole project then it could be a really huge hint why you have a problem to make simplest things work.

Can I say same about Ruby you mentioned? What’s funniest lots of Elixir developers also came from Ruby including me. Again we have read same guides. There is nothing hidden for new developers. The documentation is even improved from version to version. The whole community is really open and willing to change it if you don’t understand something, but once again “I don’t understand associations in Ecto” does not helps anybody.

3 Likes

It seems you are a very hands-on person who prefers to immediately dive in and see if they can make it work. And then when an error pops up you try addressing that, one by one, until the whole thing works.

Is that the case?

If so, I can sympathize because I am like that 80% of the time and I have to tell you that while that helps net you some insights, most of the time it’s an energy drain that can be avoided by having an upfront investment in the tech you’re interested in.

As @Eiji is saying, IMO you got burned out because you have been grinding at this without asking anyone and yeah, we can’t travel back in time to fix that.

Rest assured that the official Phoenix tutorials are well up-to-date and they will work if you follow them.

However, if you want to make a basic Phoenix app and then continue with a step that’s given much later in the official tutorials (or is not there at all) then it pays off to maybe create a toy GitHub repo, attempt to get your task done and then post a link + questions on this forum.

People around here are glad to help but willingness to have done some homework gives you better chances.

5 Likes

Thank you very much for this it was exactly what I needed. I’m not delving into Guardian but I figured out how to get it working from this. Also went down a rabbit hole and learnt more about With Do so thanks for that too.

Just needed to see something like this to see how things work.

Edit: Also with regards to your second response I learn by doing things. I made the post originally because there are a bunch of tutorials to do with this topic that I couldn’t complete due to various factors. Once I see how something is working I tend to remember it will and be able to apply it pretty easily to things in the future.

All I needed to see from your post was which files you had modified. Until this point I was unsure on whether or not I was meant to be editing the Changeset, Create_Post function, Create controller function, a mix of all three or another file I wasn’t even aware of.

I’ve probably done it in the worst way imaginable, but at least I know how the concept works now.

Yeah no worries. Having more practical examples and actual working apps is indeed super valuable when learning, especially for serial bang-head-on-wall people like you and me. :grimacing::smile:

Another super good app is Plausible Analytics and they are open source.

Repo is here: GitHub - plausible/analytics: Simple, open-source, lightweight (< 1 KB) and privacy-friendly web analytics alternative to Google Analytics.

1 Like

Agreed! Most of my learning of elixir/phoenix was by looking at working code, and then checking the docs on the module to wire it as something different. After a couple of tutorials one finds it better to grab a chunk of code and see it working in your project rather than slogging through a toy tutorial project.

Using phoenix as your first web framework around this “transitory” period is especially difficult, as there’s effectively an “old” phoenix and a “new” phoenix schism with LiveView, which’ll crop up in tutorial books.

Here’s a thread with more examples to work off of:

I also reference GitHub - livebook-dev/livebook: Interactive and collaborative code notebooks for Elixir - built with Phoenix LiveView and GitHub - dashbitco/bytepack_archive: Archive of bytepack.io

I think the bytepack archive will help the most in understanding Ecto/associations.

1 Like

Unfortunately that’s true. I have had the idea to make a “cook book” website with “recipes” for various things – versioned as well – but life and other circumstances keep getting in the way, for no less than 3 years now.

However, since Elixir 1.12 and on one can use Mix.install to create what’s essentially single-file projects where the entirety of a problem and its solution can be demonstrated at a glance.

Check @Eiji’s recent replies, he posted 1 or 2 such one-file projects. Super valuable.

I am not up-to-date on LiveBook but I believe (part of) its idea is the same?

2 Likes

If you want just a small examples without any comments/info/guides then you can check this repo:

3 Likes

Yes, Mix.install may be used at the beginning of each livebook project/document to install dependencies. I’ve not had the opportunity to use livebook more in-depth, but it’s a cool project.

In fact, I would recommend using the livebook tutorials out there that paint how OTP/processes work.

In lieu of your idea of bundling a bunch of scripts, I think it would be neat to have an introduction to phoenix through livebook somehow, which shows the whole lifecycle step by step.

If one scrolls down to “Visual representations of the running system”

1 Like

I’ve been reading along, as I imagine others have as well, and can I just say how blown away I am with the patience of @Eiji and @dimitarvp and willingness to try and explore another person’s perspective.

And then to see @Kiara find the solution and, it looks, start to feel better about this process and experience and everyone find common ground and come back around together. Wow :heart:

5 Likes

Well, I’ve been banging my head against the wall an exorbitant amount of times so I can definitely sympathize with people like myself who sometimes don’t want to do a deep dive in docs and tutorials and would like to just get something off the ground.

There’s something to be said about other posters that haven’t even learned Elixir and demand solutions be done for them but I got the feeling OP is not one of them. Hence I tried to give them a shortcut.

1 Like

Exactly what I was thinking. I think it’s a big part of the succes of the elixir community. No cynism, a lot of perspective taking, and lots of patience. Exacly what José, and most of you, are all practicing and showing by example on this forum. Love it.

1 Like