Question

I have 2 scopes: with_category and simple_search. Each of them works well individually but together I can't get exactly what I need.

product.rb

has_many :categorizations, :dependent => :destroy
has_many :categories, :through => :categorizations

scope :with_category, lambda { |category_slug| 
    return {} if category_slug.blank?

    joins(:categorizations => :category).where('categorizations.category_id = ?', Category.find_by_slug(category_slug).id).uniq
  }

  scope :simple_search, lambda { |query|
    return {} if query.blank?

    where('"products"."name" ~* ? OR "products"."description" ~* ?', query, query)
  }

products_controller.rb

def index
  @products = Product.with_category(params[:category])
                     .simple_search(params[:query])
                     .paginate(:page => params[:page], :per_page => 10)
end

When I go to localhost:3000/products?category=apple-laptops I want to grab all products with current category. Instead of this my with_category scope is ignored and I can see all products. Don't know why this is happens.

From my log:

  Product Load (0.9ms)  SELECT "products".* FROM "products" LIMIT 10 OFFSET 0
  Category Load (0.7ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 2]]
  Category Load (0.8ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 4]]
  Category Load (0.7ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 10]]
  Category Load (0.8ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 5]]
  Category Load (0.7ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 18]]
  Category Load (0.7ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 1]]
  Category Load (0.8ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 3]]
  Category Load (0.7ms)  SELECT "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."product_id" = $1  [["product_id", 15]]
Was it helpful?

Solution

Have you tried to change your scopes like this?

scope :with_category, lambda { |category_slug| 
    joins(:categorizations => :category).where('categorizations.category_id = ?', Category.find_by_slug(category_slug).id).uniq unless category_slug.blank?
}

scope :simple_search, lambda { |query|
    where('"products"."name" ~* ? OR "products"."description" ~* ?', query, query) unless query.blank?
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top