views:

192

answers:

2

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 => false
  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.

A: 

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.

Corith Malin
+1  A: 

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.

John Topley