0
votes

Sorry if this question seems simple, I am very very new to Rails (just started learning a few days ago), but after consulting Google and "Agile Web Development with Rails" I can't find the answer.

I have an issue with Rails 2.3.8 creating a foreign key on two models. My tables look like this:

cars                                 manufacturer
----                                 ------------
car_make                             name
car_model                            country
car_class                            logo_url
image_url                            (and default 'id' created by Rails)
manufacturer_id
(and default 'id' created by Rails)

My 'car_make' and 'name' fields are essentially the same; every Car I create, I want to be able to associate it with an existing Manufacturer. This is the column I am trying to create FK on.

My car.rb has 'belongs_to :manufacturer', and my manufacturer.rb has 'has_many :cars' to establish a one manufacturer to many cars relationship. However, when I create a new car (via scaffolding) the manufacturer_id field is blank.

I went to my cars_controller, found the 'create' method that is being used, and tried to add the second line below:

@car = Car.new(params[:car])
@car.manufacturer_id = car.manufacturer.id  # <===

This produces a 'NameError in CarsController#create' error, and I see:

undefined local variable or method 'car' for #<CarsController:0x1034642f0>

Rails doesn't seem to like the line I've added. What am I missing to make this work?

2

2 Answers

0
votes

Well, you need to have a manufacturer available before you can attach it to the car.

@car = Car.new( params[:car] )
m = Manufacturer.first # => as you can see you must already have one made
@car.manufacturer = m
@car.save

The reason car is undefined is because, well, you haven't defined it. Which car's manufacturer did you want to assign to @car?

So basically you need to make a manufacturer before you make a car. If the form you're filling out has the data for the manufacturer then make sure to put that under a different key in params, like, say, params[:manufacturer] and do a similar thing as you're doing with the car. Maybe like:

@car = Car.new( params[:car] )
@manufacturer = Manufacturer.find_or_create_by_name_and_country( params[:manufacturer][:name], params[:manufacturer][:country] )
@car.manufacturer = @manufacturer
@car.save
0
votes

In your view, you want to generate a drop-down list for manufacturers (I would assume), so you should do something like this in the form:

<%= collection_select(:car, :manufacturer_id, Manufacturer.all, :id, :name) %>

Then your create action shouldn't need to explicitly set a manufacturer_id because it should have received that from the form.