views:

55

answers:

3

Let's presume that I have two different conditions

:conditions => ["base == ?", self.search_text]

and

:conditions => ["status = ?", "#{self.status}"]

Is there any way to merge these conditions into one query?

+1  A: 

I'm not exactly sure I understand what you're looking to do, but it sounds like what you want are named_scopes (which were changed to scopes if you're using Rails 3).

In your model you can define dynamic named scopes:

named_scope :base, lambda { |value| { :conditions => { :base => value } } }
named_scope :status, lambda { |value| { :conditions => { :status => value } } }

And then you can use these scopes as finders:

results = Model.base(self.search_text).status(self.status) to join your conditions.

You could add as many conditions as you wanted this way.

Is that what you're trying to do?

Daniel Vandersluis
This is not quite that I need sure I can write such conditions manually but I need some code which merges them and depends on number of conditions
Bohdan Pohorilets
Oh, gotcha, I misunderstood what you were asking.
Daniel Vandersluis
Yep I'll try named scopes
Bohdan Pohorilets
+1  A: 

You can define a method to merge the conditions. For example:

first_condition = ["base == ?", self.search_text]
second_condition = ["status = ?", "#{self.status}"]

def merge_conditions(array = [])
   conditions = array.map {|a| "(#{a.first})"}.join(' AND ')
   params = array.inject([]) {|new, a| new += a[1..a.size]}
   params.insert(0, conditions)   
end

and use

merge_conditions([first_condition, second_condition])

This will return

["(base == ?) AND (status = ?)", self.search_text, "#{self.status}"]

I don't know if this is the best way, but it works!

j.
Thanks for the idea I'll try your solution too
Bohdan Pohorilets
+1  A: 

What you're looking for is the #scoped method:

base = Model
base = base.scoped(:conditions => {:base => params[:search_text]}) if params[:search_text].present?
base = base.scoped(:conditions => {:status => params[:status]}) if params[:status].present?
@results = base.all(:order => "created_at DESC")

Although I linked to the 3.0 ActiveRecord code, this also works under 2.3.

François Beausoleil
I have to join 2 tables so I added :joins param to scoped
Bohdan Pohorilets