Let's say I have a Course in which Students can enroll via a Membership (e.g. a has_and_belongs_to_many relationsip of Courses and Students). Some memberships are for students who are just observing the class (not for credit, etc.), so:
class Course < ActiveRecord::Base
has_many :memberships
has_many :students,
:through => :memberships
has_many :observers,
:through => :memberships,
:source => :student,
:conditions => { :memberships => { :observer => true }}
end
Here's what works great:
observers = Course.find(37).observers
Here's what doesn't work:
new_observer = Course.find(37).observers.build(:name => 'Joe Student')
I would have thought that one could build new records using the association and that would have generated:
But instead I get:
ActiveRecord::AssociationTypeMismatch: Membership expected, got Array
I'm sure I'm totally confused about how this and would appreciate any insights! I've also tried to do this with named scopes on the Membership model, but I can't seem to get has_many to use a scope in the association.
Thanks so much for any help possible!
I believe that you have encountered a Rails bug. I tried the same thing on my box (2.3.4) and it gives me the same error which doesn't seem right at all. Additionally I also tried the work around of:
course = Course.first
course.observers << Student.create(:name => "Joe Student")
course.save
But this creates a membership with the observer field set to false!
The final ugly workaround I came up with was creating the Membership
record manually:
Membership.create!(:course => Course.first, :student => Student.first, :observer => true)
I've created a ticket for this and I'll be investigating further after breakfast.
EDIT: I have, as promised, investigated further and found if you change your :conditions
Hash to an Array such as:
:conditions => ["memberships.observer = ?", true]
It works as intended. I also have a github repository with example code and instructions to duplicate.