Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby / Rails - Can I use a joined table's scope(or class method) as part of my WHERE clause?

I want to grab all the categories that contain purchaseable products.

class Product < ActiveRecord::Base
  belongs_to :category
  scope :purchaseable, where(:available => true)
end 

class Category < ActiveRecord::Base
  has_many :products
  scope :with_purchaseable_products, ?????
end

So, I'm trying to define :with_purchaseable_products. This works:

scope :with_purchaseable_products, joins(:products).where("products.available is true").group(:id).having('count(products.id) > 0')

But that's not very DRY. Is there any way to apply my :purchaseable scope to products in my :with_purchaseable_products scope?

Thanks.

like image 571
johnnycakes Avatar asked Jul 27 '11 22:07

johnnycakes


People also ask

What is the difference between scope and class method Rails?

Scopes are just class methods. Internally Active Record converts a scope into a class method. "There is no difference between them" or “it is a matter of taste”.

What is scope how and when it is to be used in Rails models?

Scopes are custom queries that you define inside your Rails models with the scope method. Every scope takes two arguments: A name, which you use to call this scope in your code. A lambda, which implements the query.

What is ActiveRecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.


1 Answers

You should use the merge method

class Category < ActiveRecord::Base
  has_many :products
  scope :with_purchaseable_products, joins(:products).merge(Product.purchaseable).group(:id).having('count(products.id) > 0')
end

Read more on http://asciicasts.com/episodes/215-advanced-queries-in-rails-3

like image 142
Fabio Avatar answered Oct 20 '22 05:10

Fabio