Fixing ActiveRecord::Base.all and making it friendlier to named_scope
Search feature of this blog is powered by following named_scope.
named_scope :search, lambda { |search_term|
{ :conditions => ["title LIKE :search_term or body LIKE :search_term", { :search_term => "%#{search_term}%"} ] }
}
I want to search for all sinatra related articles.
>> Article.search('sinatra')
SELECT * FROM `articles` WHERE (title LIKE '%sinatra%' or body LIKE '%sinatra%')
I want to search for all articles in published status.
>> Article.all(:conditions => {:status => 'published'})
SELECT * FROM `articles` WHERE (`articles`.`status` = 'published')
Now I want to combine the above two requirements: search for ‘sinatra’ related articles which are in ‘published’ status. Should be easy, Right.
>> Article.all(:conditions => {:status => 'published'}).search('sinatra')
NoMethodError: undefined method `search' for #
Now try the same search as above in reverse order: put named_scope ‘search’ first and then apply ‘all’.
>> Article.search('sinatra').all(:conditions => {:status => 'published'})
SELECT * FROM `articles` WHERE (`articles`.`status` = 'published') AND (title LIKE '%sinatra%' or body LIKE '%sinatra%')
This one worked. Why is that?
That’s because ActiveRecord::Base.all method is defined like this
def all(*args) find(:all, *args) end
So the main problem is that all is not a named_scope. And since it is not a named_scope Article.all(:conditions => {:status => ‘published’}).search(‘sinatra’) failed.
Fix is to create a named_scope called all.
module ActiveRecord
class Base
named_scope :all, lambda { |args| args ||= {} }
end
end
Now the order does not matter and you can use all any way you please.


Recent comments
1 year 23 weeks ago
1 year 23 weeks ago
1 year 25 weeks ago
1 year 27 weeks ago
1 year 42 weeks ago
1 year 45 weeks ago
1 year 45 weeks ago
1 year 45 weeks ago
1 year 46 weeks ago
1 year 48 weeks ago