Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a Rails 3 Dynamic Scope Conditional?

Tags:

I'd like to make a dynamic named scope in rails 3 conditional on the arguments passed in. For example:

class Message < AR::Base
  scope :by_users, lambda {|user_ids| where(:user_id => user_ids) }
end

Message.by_users(user_ids)

However, I'd like to be able to call this scope even with an empty array of user_ids, and in that case not apply the where. The reason I want to do this inside the scope is I'm going to be chaining several of these together.

How do I make this work?

like image 333
tdahlke Avatar asked Apr 21 '11 19:04

tdahlke


1 Answers

To answer your question you can do:

scope :by_users, lambda {|user_ids| 
  where(:user_id => user_ids) unless user_ids.empty?
}

However

I normally just use scope for simple operations(for readability and maintainability), anything after that and I just use class methods, so something like:

class Message < ActiveRecord::Base

  def self.by_users(users_id)
    if user_ids.empty?
      scoped
    else
      where(:user_id => users_id)
    end
  end

end

This will work in Rails 3 because where actually returns an ActiveRecord::Relation, in which you can chain more queries.

I'm also using #scoped, which will return an anonymous scope, which will allow you to chain queries.

In the end, it is up to you. I'm just giving you options.

like image 77
Mike Lewis Avatar answered Feb 09 '23 03:02

Mike Lewis