user979051
user979051

Reputation: 1267

Rails 3.2 Query

I have the following Model classes:

class OptionCategory < ActiveRecord::Base
  attr_accessible :disabled, :list_index, :name
  has_many :options
end


class Option < ActiveRecord::Base
  attr_accessible :disabled, :name, :option_category_id
  belongs_to :option_category
  has_and_belongs_to_many :products
end


class Product < ActiveRecord::Base
  attr_accessible :annual_fee, :bal_transfer_intro_apr_end, :bal_transfer_intro_apr_start, :balance_transfer_fee, :description, :image, :image_cache, :name, :pur_intro_apr_end, :pur_intro_apr_start, :sign_up_bonus, :sign_up_bonus_type, :url
  mount_uploader :image, ImageUploader

  has_and_belongs_to_many :options
end

In one of my controllers I receive an array of option ids, I would like to query for Products that have options that match those ids. Is there an easy way to do this in Rails? Thanks!

Upvotes: 0

Views: 90

Answers (2)

user979051
user979051

Reputation: 1267

Product.joins(:options).where(:options => {:id => params[:options]}).group(:id)

Upvotes: 0

user229044
user229044

Reputation: 239230

You can find all your Options and optimize away the N+1 by using includes:

Option.includes(:products).where(:id => array_of_ids)

This will perform a single select * from options where id in [array_of_ids] to load the options, extract the product_id fields, and perform a single additional select * from products where id in [product_ids] query.

You can make this easier on yourself by using has_many :through, and creating a model to wrap the joining table. If this model were called ProductOptions, you would be able to simply do this:

Product.find(ProductOptions.where(:option_id => array_of_option_ids).map(&:product_id).uniq)

Upvotes: 1

Related Questions