Nick
Nick

Reputation: 9896

Rails - Select Model that matches two separate association conditions

I have three models, Model, ModelType, and ModelCategory. They're connected to each other via an association table such as ModelTypeRelationship and ModelCategoryRelationship.

# app/models/model.rb
class Model < ActiveRecord::Base
  has_many :model_type_relationships, dependent: :destroy
  has_many :model_category_relationships, dependent: :destroy
  has_many :types, through: :model_type_relationships
  has_many :categories, through: :model_category_relationships
  ...
end

NOTE: model1.type would return an array of ModelType objects that are associated with model1. models may be associated with multiple model_types or model_categories.

I'd like to be able to select a random Model such that it is of type1 and category1.

I was having some success selecting a Model of type1, but I got stuck after that. Here is my code for that selection:

ModelType.find_by_name("type1").models.find(:first, :order => "Random()")

NOTE: model_type1.models returns an array of Model objects of type1.

Upvotes: 0

Views: 270

Answers (1)

castilhor
castilhor

Reputation: 36

First, add a scope to your ModelType and ModelCategory models:

scope :named, lambda { |name| where(arel_table[:name].eq(name)) }

You want to select "models", so it's natural to start the query from Model class instead:

Model.joins(:types).scoped.merge(ModelType.named("type1"))

And finally you can combine scopes on that way:

Model.joins(:types, :categories).scoped.merge(ModelType.named("type1"))
  .scoped.merge(ModelCategory.named("category1"))

Obs: I'm presuming that ModelType and ModelCategory have the attribute :name, so you can filter by that.

Upvotes: 1

Related Questions