tblev
tblev

Reputation: 462

Phoenix - 1 to none relationship

I'm looking for a sort of one-way relationship that I would best describe as a 1-0.

I want essentially a car to have a certain engine, but not an engine to have a certain car...

  1. Car has one Engine but can have many different engines
  2. Engine can belong to many different cars at once and in order for this to be true, it needs to be independent of Car in the database. (No car id for engine, since the same one can be referenced by many cars.)

This is what I currently have:

  schema "cars" do
     has_one :engine, Engine

     field :make, string
  end

  create table(:cars) do
     add :make, string
     add :engine_id, :integer
  end 

  schema "engines" do
     add :pistons, integer
  end

  create table(:engines) do
     add :pistons, integer
  end 

The specific issue I'm having with this type of relationship is:

unknown field `:engine_id` given to cast. Either the field does not exist or it is a :through association (which are read-only).

Which means that the has_one is clearly not adding an engine_id field into the schema for it to cast it. The functionality I want is produced when I replace the has_one with a belongs_to relationship to car, but that doesn't make any logical sense...cars don't belong to engines...engines belong to cars.

Imagine a dropdown in a website...and you want to give the user the ability to choose a different amount of pistons for an engine, or some characteristic of an engine that has multiple options...like fuel type. The engine won't belong to the pistons or the fuel type...

What is the proper way for this relationship to be created?

Upvotes: 0

Views: 95

Answers (1)

Brett Beatty
Brett Beatty

Reputation: 5973

As far as I'm aware belongs_to is the correct association for the car.

You're right it doesn't make sense in English to say a car belongs to an engine, but the docs for belongs_to/3 suggest it's what you're looking for:

You should use belongs_to in the table that contains the foreign key.

And it sounds like has_many/3 is what you want for engines. In a one-to-many relationship the "one" table (engines) doesn't have IDs for the "many" table (cars); it instead relies on the "many" table (cars) having a foreign key that points back to the "one" table (engines).

Upvotes: 1

Related Questions