Many-to-Many: Where to add the children?


#1

I have two classes Person and Job defined as follows:

class Person < ActiveRecord::Base
:has_and_belongs_to_many jobs

def add_job(job_name)
  job = Job.find_by_name(job_name)  # See if this job exists
  if job.nil?                       # If this job doesn't exist
    job = Job.new                   # Create a new job
    job.name = job_name             # with the given name
  end
  jobs << job                       # Add to this person's jobs
end

end

class Job < ActiveRecord::Base
:has_and_belongs_to_many people
end

I also have a controller that uses the add_job method in Person as
follows:

… omitted code

person = Person.new
person.add_job(“teacher”)
person.save!

Now, when the job with the name “teacher” already exists, the
relationship between the new Person and the existing Job is not saved.
If the job does not exist, it saves the new Job and creates the
relationship. However, if I change the code of the add_job method as
follows:

def add_job(job_name)
job = Job.find_by_name(job_name) # See if this job exists
if job.nil? # If this job doesn’t exist
job = Job.new # Create a new job
job.name = job_name # with the given name
jobs << job # and add to this person’s jobs
else # Otherwise, if it does exist
job.people << self # Add this person to the job’s
people
end
end

It saves the relationship correctly regardless of whether or not the Job
already exists. My question is, why? – Why do I need to add the
person to the job’s people array to get the assocation to save when the
Job already exists?


#2

Jason F. wrote:

… omitted code

person = Person.new
person.add_job(“teacher”)
person.save!

Now, when the job with the name “teacher” already exists, the
relationship between the new Person and the existing Job is not saved.
If the job does not exist, it saves the new Job and creates the
relationship.

In your real code Does Person have any other associations?
There is a Active Record bug that causes join table entries for
habtm relations on unsaved objects to not be added in some
circumstances when other associations have been defined:
http://www.ruby-forum.com/topic/48785
http://www.ruby-forum.com/topic/48816

Try:

person = Person.create!
person.add_job(“teacher”)
person.save!


We develop, watch us RoR, in numbers too big to ignore.


#3

Mark Reginald J. wrote:

In your real code Does Person have any other associations?

Yes, Person has the following relationships:

belongs_to :family
has_many :kids
has_and_belongs_to_many :organizations

Job is also in another many-to-many relationship:

has_and_belongs_to_many :companies

There is a Active Record bug that causes join table entries for
habtm relations on unsaved objects to not be added in some
circumstances when other associations have been defined:
http://www.ruby-forum.com/topic/48785
http://www.ruby-forum.com/topic/48816

Try:

person = Person.create!
person.add_job(“teacher”)
person.save!

Thanks for the tip, I’ll read those articles and give this a shot!


#4

Mark Reginald J. wrote:

This is now aparently fixed in trunk:
http://dev.rubyonrails.org/changeset/3332

Thanks, again!


#5

Jason F. wrote:

Yes, Person has the following relationships:

belongs_to :family
has_many :kids
has_and_belongs_to_many :organizations

Job is also in another many-to-many relationship:

has_and_belongs_to_many :companies

Yes, two habtms is a bug trigger.

This is now aparently fixed in trunk:
http://dev.rubyonrails.org/changeset/3332


We develop, watch us RoR, in numbers too big to ignore.