Ruby on Rails - has one and belongs to many relationship
This question is related to ruby on rails ActiveRecord associations and how to generate those migrations.
I'm trying to build a web-app for a documentation/data management system and I have two models - Arg and Descriptor. (The reason for making a descriptor an object rather than an attribute is for multiple Args to share the same description). The relationship between Args and Descriptors is as follows: an Arg has ONLY one descriptor. A Descriptor has MANY Args.
Basically, in the code, I would like to be able to do the following:
a1 = Arg.first
a1.descriptor = Descriptor.first
d1 = Descriptor.last
d1.args << Arg.last
d1.args << Arg.first
Currently I have this set up:
class Descriptor < ActiveRecord::Base
has_and_belongs_to_many :args
end
class Arg < ActiveRecord::Base
has_one :descriptor
end
I also ran these migrations:
create_table :args do |t|
t.string :name
t.timestamps
end
create_table :descriptors do |t|
t.string :name
...
t.timestamps
end
add_column :descriptors, :switch_id, :integer
create_table :args_descriptors, :id => false do |t|
t.column :arg_id, :integer, :null => f开发者_运维百科alse
t.column :descriptor_id, :integer, :null => false
end
When i try all of the above, I can't get two Args to share a Descriptor object for some reason. for example:
>> Arg.first.descriptor
=> nil
>> Arg.first.descriptor = Descriptor.last
=> #<Descriptor id: 9, name: "....
>> Arg.last.descriptor
=> nil
>> Arg.last.descriptor = Descriptor.last
=> #<Descriptor id: 9, name: "....
>> Arg.first.descriptor
=> nil
Why is the first Arg's descriptor nil now?? am i missing a column in my database? am i not specifying the relationship correctly?
I'm not very proficient in rails nor the migrations/databases. If you are explaining a concept, please please please try to provide both ActiveRecord code examples as well as Migrations code examples. Thanks.
I believe these are the associations and migrations that you need:
class Descriptor < ActiveRecord::Base
has_many :args
end
class Arg < ActiveRecord::Base
belongs_to :descriptor
end
create_table :args do |t|
t.string :name
t.integer :descriptor_id
t.timestamps
end
create_table :descriptors do |t|
t.string :name
...
t.timestamps
end
Note that if you want to store extra information against the association between Arg
and Descriptor
then you'll need a join model which you get using the has_many :through association
.
You're actually going to want an intermediate table between these two objects. In the database world this is called a "mapping" table. In Ruby you want to use the has_many through association.
http://railscasts.com/episodes/47-two-many-to-many
Updated with better article explaining concept.
精彩评论