has_many: Adds the methods for retrieval and query of collections of associated object.
belongs_to: Adds the methods for retrieval and query of single associated object for which this object holds an id
so, if you dont require to use methods on both the associated objects you may choose not the set the association accordingly.But its mandatory to put the foreign key in the model where the one instance is associated to one and only one instance of the other object that is: 'belongs_to' model.
Explaination:
lets consider schema like:
create_table "cars", :force => true do |t|
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.datetime "created_at"
t.datetime "updated_at"
end
and models as:
class User < ActiveRecord::Base
end
class Car < ActiveRecord::Base
belongs_to :user
end
the result is:
D:\temp>rails c
Loading development environment (Rails 3.0.10)
irb(main):001:0> U = User.first
=> #<User id: 1, created_at: "2011-11-22 06:43:04", updated_at: "2011-11-22 06:43:04">
irb(main):002:0> C = Car.first
=> #<Car id: 1, user_id: 1, created_at: "2011-11-22 06:43:34", updated_at: "2011-11-22 06:43:34">
irb(main):003:0> C.user
=> #<User id: 1, created_at: "2011-11-22 06:43:04", updated_at: "2011-11-22 06:43:04">
irb(main):004:0> U.cars
NoMethodError: undefined method `cars' for #<User:0x3d19970>
from C:/Ruby/lib/ruby/gems/1.9.1/gems/activemodel-3.0.10/lib/active_model/attribute_methods.rb:392:in `method_missing'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.10/lib/active_record/attribute_methods.rb:46:in `method_missing'
from (irb):4
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands/console.rb:44:in `start'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands/console.rb:8:in `start'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
irb(main):005:0> exit
And if the models are like below:
and models as:
class User < ActiveRecord::Base
has_many :cars
end
class Car < ActiveRecord::Base
end
Result is:
D:\temp>rails c
Loading development environment (Rails 3.0.10)
irb(main):001:0> U = User.first
=> #<User id: 1, created_at: "2011-11-22 06:43:04", updated_at: "2011-11-22 06:43:04">
irb(main):002:0> C = Car.first
=> #<Car id: 1, user_id: 1, created_at: "2011-11-22 06:43:34", updated_at: "2011-11-22 06:43:34">
irb(main):003:0> U.cars
=> [#<Car id: 1, user_id: 1, created_at: "2011-11-22 06:43:34", updated_at: "2011-11-22 06:43:34">]
irb(main):004:0> C.user
NoMethodError: undefined method `user' for #<Car:0x41524c8>
from C:/Ruby/lib/ruby/gems/1.9.1/gems/activemodel-3.0.10/lib/active_model/attribute_methods.rb:392:in `method_missing'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.10/lib/active_record/attribute_methods.rb:46:in `method_missing'
from (irb):4
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands/console.rb:44:in `start'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands/console.rb:8:in `start'
from C:/Ruby/lib/ruby/gems/1.9.1/gems/railties-3.0.10/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
irb(main):005:0>