Reputation: 366
I'm trying to write an if statement that will find an instance of an object in a collection within another collection...
House
has_many :occupants
Occupant
has_many :shirts
belongs_to :house
Shirt
belongs_to :occupant
So if I want check if any of the occupants of house own a white shirt, I want to do something like this:
<% if @house.occuptants.shirts.where(:color => 'white') %>
However when I do that I get an error:
undefined method `shirts' for #< Occupant::ActiveRecord_Associations_CollectionProxy
I believe because occupants is a collection in this case, but I'm not sure what the correct approach or syntax should be.
Upvotes: 1
Views: 1377
Reputation: 4115
Something simpler and that will help you later for different use cases is to add more to the relationships:
class House
has_many :occupants
has_many :shirts, through: :occupants
end
class Occupant
has_many :shirts
belongs_to :house
scope :females, -> { where(...) } # This is homework for you: http://guides.rubyonrails.org/active_record_querying.html#scopes
end
class Shirt
belongs_to :occupant
end
If you have a House
instance:then you can check for occupants with white shirts as below:
<% if @house.shirts.where(color: 'white').exists? %>
and to check for female occupants with white color shirts, do:
<% if @house.occupants.females.select { |o| o.shirts.where(color: 'white').exists? } %>
Upvotes: 3
Reputation: 258
I would go for a presenter/decorator in this scenario.
Use draper to decorate the house object like:
# /app/decorators/house_decorator.rb
class HouseDecorator < Draper::Decorator
def count_occupants_with_white_shirts
object.occupants.joins(:shirts).where(shirts: { color: 'white' } ).count
end
end
Then in your view:
<% if @house.count_occupants_with_white_shirts > 0 %>
Hope that helps.
NOTE: If you don't want an additional dependency(Draper) you can also put that method inside you House
model
Upvotes: 0