2
\$\begingroup\$

I have following relationship schema:

class Participation
  belongs_to :toon
  belongs_to :person

  validates :role, :presence => true
end

class Toon
  has_many :participations
  has_many :people, :through => :participations
end

class Person
  has_many :participations
  has_many :toons, :through => :participations
end

I want to get people association related to toon, but filtered by role attribute value. I need something like toon.people_with_role('producer').

class Toon < ActiveRecord::Base
  has_many :participations
  has_many :people, :through => :participations

  def people_with_role(role)
    Participation.where(:toon_id => self, :role => role).map(&:person)   
  end
end

It works, but I'm not sure that it is a best way to do it.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Here is another way to filter people by role:

class Participation < ActiveRecord::Base
  belongs_to :toon
  belongs_to :person

  validates :role, :presence => true
end

class Person < ActiveRecord::Base
  has_many :participations
  has_many :toons, :through => :participations
end

class Toon < ActiveRecord::Base
  has_many :participations
  has_many :people, :through => :participations do
    def with_role(role)
      where('participations.role' => role)
    end
  end
end

Now, you can get the people fitered by role: toon.people.with_role('producer').

\$\endgroup\$
1
  • \$\begingroup\$ Great, I don't knew that it can be done in that way. \$\endgroup\$ Commented Jan 23, 2012 at 13:55
0
\$\begingroup\$

I would create a scope under 'Person' for this, that way you can chain it together with other Person scopes. something like this should work (may have slight syntax errors).

scope :for_toon_with_role, lambda { |toon, role| joins(:participations).where(:participations => {:role => role, :toon_id => toon.id }) }

That way you can call it like this:

Person.for_toon_with_role(toon, 'role').all

Check out more info on rails scopes here:rails scopes

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.