4
votes

I have a user profile model with the following schema:

  schema "user_profiles" do
    field :birthday, Ecto.Date
    field :gender, :string
    field :first_name, :string
    field :last_name, :string
    field :description, :string
    field :username, :string

    # Associations
    belongs_to :user, User

    timestamps
  end

I also have a location model with the following schema:

  schema "locations" do
    field :name, :string
    field :admin_1, :string
    field :admin_2, :string
    field :country, :string
    field :country_abbreviation, :string
    field :code, :string
    field :latitude, :decimal
    field :longitude, :decimal

    timestamps
  end

A location is a city like Paris, France. Many user profiles can be associated with the same location. But a location doesn't really need to be aware that user profiles exist.

I want to add a location association to the user profile schema. I do not want to user has_one because the relationship is not one-to-one. I do not want to add any associations on the location schema to user profile, either.

I have looked at the documentation for Ecto and I am at a loss for how to express this association.

I have consulted the following page: https://hexdocs.pm/ecto/Ecto.Schema.html

I am probably missing something basic but I did try more than a few things before asking this question.

1
Sounds like you want a many_to_many association. This means that the user can have many locations and the location can belong to many users. This is typically done through a joins table which would be called e.g. location_profiles. Here is a link that goes into more detail: link - Harrison Lucas
@HarrisonLucas Thanks for the comment. I actually want just to have one location per user profile. And one location can "belong to" many user profiles. In the database, location is just a foreign key on the user profile table. - michaels
ah right in that case why not just do a a Has_many and belongs_to? E.g. Profilea belongs to locationa and Profileb belongs to locationa. Therefore, location has_many profiles, and a profile belongs to a single location? - Harrison Lucas
@HarrisonLucas If that's the case, do I have to add a foreign key to my location table in the database? - michaels
see below for my answer - Harrison Lucas

1 Answers

3
votes

One solution is to do a simple has_many and belongs_to relationship between the two models where the profile will belong to a relationship.

This relationship will mean that a location can have many profiles associated with it, whereas a profile can only have one location.

E.g.

Works:

Profile1:London √

Profile2:London √

Wrong:

Profile1:London X

Profile1:France X

This is how you would go about implementing it.

#web/models/location.ex
schema "location" do
  has_many :profiles, MyApp.Profile
end

#web/models/profile.ex
schema "profile" do
  belongs_to :location, MyApp.Location
end

Then on your profile_table migration you would have:

add :location_id, references(:locations)

You don't need a foreign key on the location model, only the profile model.