Forum: Ruby on Rails Many-to-Many: Where to add the children?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E4f8e60d8db78514931ab6ff4073ab4f?d=identicon&s=25 Jason Fox (jfoxny)
on 2005-12-29 05:31
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?
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2005-12-29 14:32
(Received via mailing list)
Jason Fox 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.
E4f8e60d8db78514931ab6ff4073ab4f?d=identicon&s=25 Jason Fox (jfoxny)
on 2005-12-29 15:25
Mark Reginald James 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!
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2005-12-29 16:30
(Received via mailing list)
Jason Fox 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.
E4f8e60d8db78514931ab6ff4073ab4f?d=identicon&s=25 Jason Fox (jfoxny)
on 2005-12-29 16:53
Mark Reginald James wrote:

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

Thanks, again!
This topic is locked and can not be replied to.