Rails associations

Hi,

I am new to RoR and have been pulling my hair out trying to figure out
associations.

Lets say I have 2 tables: vehicles and vehicle_types. ONE vehicle HAS
ONE vehicle_type. Therefore, in my opinion, vehicle_type belongs_to
vehicle.

Hence, vehicle_types will contain the vehicle foreign key. To me this is
already weird. I would like vehicle_types to be a table containing a
column that lists types of vehicles- "truck", "car", "bus", etc. It does
not need to know what vehicle is associated with it. The vehicles table
needs to know what vehicle_type it is.

I would like to use the vehicle_types table to populate a Select Menu on
a form. If I create the associations as suggested by RoR, with the
foreign key going on the belongs_to table (vehicle_types), the Select
Menu would be populated with duplicate vehicle_types. EG:

vehicle_id vehicle_type_id type
    1 1 car
    2 2 truck
    3 3 car

Does this make sense?

Like I said I have spent days reading over the associations again and
again but I just can't figure it out. Any help would be greatly
appreciated.

Thanks.

Hi,

I am new to RoR and have been pulling my hair out trying to figure out
associations.

Lets say I have 2 tables: vehicles and vehicle_types. ONE vehicle HAS
ONE vehicle_type. Therefore, in my opinion, vehicle_type belongs_to
vehicle.

No, the names of associations are confusing at times. In your case a
vehicle type can be associated with many vehicles, therefore
vehicle_type has_many vehicles. A vehicle is only of one type, so
vehicle belongs_to vehicle_type, and it is the vehicle that has the
vehicle_type_id.

Colin

Thank you so much for your reply Colin.

I believe you are spot on with your answer and what you suggest will
work and is the correct solution.

For sake of my sanity though, is this solution more of a Rails
convention or have I been getting standard database design confused in
my head for a number of years? To my previous understanding I still see
it as one vehicle has one vehicle_type. Almost like vehicle_type is a
child table to the parent vehicle. Is this wrong thinking for all
database design or just Rails conventions?

Thank you so much for your reply Colin.

I believe you are spot on with your answer and what you suggest will
work and is the correct solution.

For sake of my sanity though, is this solution more of a Rails
convention or have I been getting standard database design confused in
my head for a number of years? To my previous understanding I still see
it as one vehicle has one vehicle_type. Almost like vehicle_type is a
child table to the parent vehicle. Is this wrong thinking for all
database design or just Rails conventions?

vehicle_type cannot be like a child to the vehicle, because it is
associated with multiple vehicles, how can it be a child of multiple
parents? It is the other way round if you want to think of child and
parent. A parent (vehicle type) has many children (vehicles), but a
child (vehicle) belongs to a single parent. If you are thinking in
conventional database design just remember that it is the table that
includes the foreign key (vehicle.vehicle_type_id in this case) that
must specify the belongs_to association.

Colin

Once again, fantastic help Colin. Great explanation and it is all
becoming much clearer for me now. Your help was very much appreciated.

Sometimes the names can have extra baggage that makes it confusing - for example, it seems clearer to say “one vehicle belongs to a single vehicle category”.

–Matt Jones

Ok, the associations are getting the better of me again. My models for
Business, VehicleType and Vehicle.

class Business < ActiveRecord::Base
  has_many :vehicles
end

class VehicleType < ActiveRecord::Base
  has_many :vehicles
end

class Vehicle < ActiveRecord::Base
  belongs_to :business
  belongs_to :vehicle_type
end

Now, my problem is in creating a new vehicle. I can create a Business
and VehicleType just fine, but when I try to create a Vehicle I run into
problems with the foreign keys.

If I try:
first_vehicle = Vehicle.new(:veh_name => "test")
#then I try adding the new vehicle to my existing business
business.vehicles << first_vehicle

it generates an error that the foreign key for the vehicle_types table
cannot be null. If I try to append the vehicle to the VehicleType first
I get an error that the business_id cannot be null.

Any ideas here?

It sounds like you’re running up against database foreign key constraints: your model needs to have those id attributes filled in before you can save it. (This is often caught with validations at the rails application layer too, with validates :vehicle_type, presence: true)

This is one possible approach:

business = Business.first

car = VehicleType.find_by_name(“car”)

first_vehicle = Vehicle.new

first_vehicle.business = business

first_vehicle.vehicle_type = car

first_vehicle.save

Or another way:

first_vehicle = Vehicle.create do |v|

v.business = business

v.vehicle_type = car

end

Or:

first_vehicle = business.vehicles.build(vehicle_type: car)

first_vehicle.save

Or again:

first_vehicle = business.vehicles.create(vehicle_type: car)

Wow. Amazing response Andrew. I will report back if I have any trouble
implementing this.

Is there a guide anywhere for best practices with Rails? You have given
some great examples but as a newbie I would like to commit to my memory
those practices that are highly recommended.