Searchlogic makes searching models easier than ever with its assortment of named scopes. In this episode I show you how to create simple and advanced searches.
Thanks for this screencast -- this would have saved me a lot of time last week! ;) I feel like the safety/security issues of using this method for a public search feature could be averted if before using the search method, you slice the params hash to only include the parameters that were expected from the form. Then any other parameters wouldn't be acted upon. What do you think of that?
Also, do named scopes (as well as authlogic) automatically escape values, removing the need to call h() manually?
I don't think you have to put a route. @search is an array of products stored in the index action of Products controller, so it should do the trick with form_for.
Ryan,
great episode, as always. In any event I am stuck on the hirb stuff, I tried rtfm on the hirb page but it doesn't work can you give me a quick pointer on this one?
I have a question, in the collection_select if users select blank, will it means select :all or select blank? I hope it's the former one, I'll try it out later.
Nice! Still playing around with it...getting inconsistent results. Maybe my rails version(2.2.2)?
Also, how does one "preload" commands like the ActiveRecord::Base::logger = Logger.new(STDOUT) or a require "<blah>" so they are available as soon as you start the console?
How do I implement searching multiple columns? Say I have an address book database and I want one search field to query the name column, the address column and the email column. How might this be accomplished using searchlogic and a single search field?
@BasicObject I ran into the same problem with SearchLogic and decided to extend my own ar_helper plugin to do just that, take a look at the #search method here at: http://github.com/vanntastic/ar_helper/tree/master. In your example above, you can do this instead:
While this searchlogic is great, it's pretty outdated. You should not use 'searchlogic' gem. Instead grab the 'binarylogic-searchlogic'. See: http://www.binarylogic.com/2009/06/15/searchlogic-v2-officially-released/
Basically it's a complete rewrite that deals with searches quite differently and way cleaner.
Packed full of win! The underscore in IRB hint alone was well worth the download, but being able to get rid of several lines of complex code using searchlogic.... excellent episode. Keep it up.
@jDeppen: go ahead and use SearchLogic for the front-end search, but make sure the controller scrubs out any values in the search hash that you don't want there.
http://gist.github.com/176481
This way, you can even define defaults for the search.
I was surprised that there was no mention SearchLogic's interoperability with will_paginate. Paginating search seems to be one of the big hurdles newbie Rails developers tackle.
All one needs to do is call the paginate method on the search, thus:
I looked at the code and i believe that the method which is responsible for processing the "or" conditions, don't get called if you use the User.search ... form.
But I am not sure.
I am still learning the "meta-programming" thing in ruby. But I believe Dave Thomas or Paolo Perrotta sad there is no such thing, its just programming ;-)
I don't have a github account yet, but can somebody post there a comment about the searchlogic issue.
@ryan Your videos are great. They help me to forget php ;-)
If you want to offer your users a simple search box instead of a complex form to search your models, check out scoped_search: http://github.com/wvanbergen/scoped_search
class Model < ActiveRecord::Base
scoped_search :on =>[:name, :description, :created]
end
Model.search_for(params[:q]).paginate(...)
This will work with queries like:
- keyword1 keyword2 keyword3
- (a | b) & created > 2009-01-01
- name = "Willem van Bergen"
At the end of the video Ryan mentions the form_for method should not be used for public facing pages. He says to setup custom forms in those situations. What exactly is meant by that? Does that mean to use form_tag to build the form? If so, how do I do this using multiple scopes?
@Tim Gossett - You need to post what you said about getting will_paginate to work with searchlogic in the forums. This is the only place I found that solution... even though it's a simple easy one some people don't think of doing that. Thanks sooo much!!
@hartwig @Ryan @eric,
i have the same problem with the or-condition. i.e. User.search(:firstname_or_lastname_like => "foo") is not working. In the console i get the notice: #<Searchlogic::Search:0x34503f0 @conditions={:firstname_like_or_lastname_like=>false}, @current_scope=nil, @klass=User(id: integer, ....
Has anyone found a solution to this problem?
Great post thought, Ryan. As always.
First of all, thanks for the awesome screencast. I just came across this site recently and it's been an amazing resource so far.
But I'm having some trouble. I've been able to implement the search form on my model's index.html.erb file, but putting it in the application.html.erb file to act as a global search accessible from any page results in me getting whiny_nil errors all over the place.
My app is a listing of bars and their respective specials. So the search works great on the index page where all the bars are listed. I can search just fine, everything works as expected from that side of things.
But when I click a link to see additional details about the bar, THAT is when I get the whiny_nil.
I just don't know what to do or why it doesn't work. I can't seem to find anything online about implementing a global search using SearchLogic. :(
Searchlogic V2 is out.
Is this for V2? If not, could you please show one for V2?
Would be nice to see how you go abouts setting up routing for the search resource :) thanks
hi ryan
great post. I managed to get searchlogic 2.3 working for me. When I use will_paginate, the only thing that breaks is the "order".
When i load my search results page, i seem to get an error indicating "order" is not defined.
I later found out that to get ordering to work again, i need to be able to generate the same url (with params) and append the order clause to it.
1) how do i do it?
2) with searchlogic 2.3.+ and will_paginate, how can we still maintain using "order" in the view as per your tute?
I get a runtime error when i try to access the search form page. I can search fine in the script/console but when i got to my search page i get " Showing app/views/groups/search.html.erb where line #1 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"
I'm really excited about implementing search with this Railscast, but I keep getting an error I can't find help on. When I render the search form, I keep getting:
undefined method `nil_class_path' for #<ActionView::Base:0x3775a94>
Is it possible to have an index with just the search form and when a user "submits" then the results are printed below? Currently I have an unfiltered list that becomes smaller upon "Submit". Also I can create dropdowns using searchlogic, but they don't render results (filter my list) when I hit submit.
I am a newbie, so bear with me.
My newly create site using searchlogic is here: http://grants.firelightfoundation.org
It couldn't have been done better. From a noob point of view, its a gem. Though my needs didn't exactly fit with the example, a peek at the documentation gave me what i wanted. Nice work!
Have been tinkering with thinking sphinx but that might be overkill on the project i am currently working on. The only reservation I have about searchlogic is that the owner of the project wants clean urls, searchlogic doesnt seem to have this on first look. Any ideas for cleaning up the urls?
I can not get searchlogic to work when using a has_many through model. Is it supposed to? I get method_missing when I try to search for something in the has_many table.
In response to questions about Rails 3 - It appears (from looking on the the github page issues section) that searchlogic is pretty heavily tied to ActiveRecord 2 and not trivial to switch over. There is a port in progress at railsdog/searchlogic currently in it's 3rd or fourth release candidate. I haven't been able to get it to work yet, but it's worth checking out.
Oops... Sorry... Chirstopher Small isn't a spammer.... clicked one too much... Apparently searchlogic still isn't Rails3 ready :( Maybe you should put a big warning on top of this post (and as well for all others plugins/gems not compatible with rails3)
Would be really helpful if searchlogic would be ported to rails 3. I want to upgrade a rails 2.3 project to rails 3, would hate to have to remove searchlogic.
Oh well.. that's a problem with most rails plugins/gems - they stop being upgraded after a while and when you have an older project that uses them then you are out of luck.
I second the warning aboiut Searchlogic not working with Rails 3. Took me a while to figure this one out, and I had gotten all excited about using it too :(
It produces this error:
error [long path] 'alias_method': undefined method merge_joins' for classClass' (NameError)
Another great cast Ryan. Thanks.
One small bug I found. At 13:00 you call it Authlogic, instead of Searchlogic. Its probably too late to fix that but I thought I'd mention it :)
Great episode! But I have one question.
How come form_for @search get's mapped to the index action of ProductsController, where is that route configured?
Great job Ryan, this is a great video. You did an excellent job. It definitely beats my boring tutorials.
Keep up the good work.
Hi Ryan,
Thanks for this screencast -- this would have saved me a lot of time last week! ;) I feel like the safety/security issues of using this method for a public search feature could be averted if before using the search method, you slice the params hash to only include the parameters that were expected from the form. Then any other parameters wouldn't be acted upon. What do you think of that?
Also, do named scopes (as well as authlogic) automatically escape values, removing the need to call h() manually?
Cheers,
Alex
@Roy van der Meij
I don't think you have to put a route. @search is an array of products stored in the index action of Products controller, so it should do the trick with form_for.
Ahem, I mean searchlogic in the comment above.
Ryan,
great episode, as always. In any event I am stuck on the hirb stuff, I tried rtfm on the hirb page but it doesn't work can you give me a quick pointer on this one?
Hi Ryan,
I have a question, in the collection_select if users select blank, will it means select :all or select blank? I hope it's the former one, I'll try it out later.
Nice! Still playing around with it...getting inconsistent results. Maybe my rails version(2.2.2)?
Also, how does one "preload" commands like the ActiveRecord::Base::logger = Logger.new(STDOUT) or a require "<blah>" so they are available as soon as you start the console?
@vinnyt For hirb documentation see http://tagaholic.me/hirb/doc and http://github.com/cldwalker/hirb/tree/master#readme .
How do I implement searching multiple columns? Say I have an address book database and I want one search field to query the name column, the address column and the email column. How might this be accomplished using searchlogic and a single search field?
@BasicObject I ran into the same problem with SearchLogic and decided to extend my own ar_helper plugin to do just that, take a look at the #search method here at: http://github.com/vanntastic/ar_helper/tree/master. In your example above, you can do this instead:
<script src="http://gist.github.com/174016.js"></script>
I'm trying to use Searchlogic and allow users to save searches for my real estate website. I'm trying to make it a ListingSearch resource.
It seemed like Ryan was suggesting using Searchlogic for only admin purposes. Should I roll my own "old school" search?
Anyone have any thoughts?
@chris make an .irbrc file in your home folder and put this in the file
http://gist.github.com/174133
enjoy.
While this searchlogic is great, it's pretty outdated. You should not use 'searchlogic' gem. Instead grab the 'binarylogic-searchlogic'. See: http://www.binarylogic.com/2009/06/15/searchlogic-v2-officially-released/
Basically it's a complete rewrite that deals with searches quite differently and way cleaner.
Actually it seems that they are identical now. Silly me.
Great screencast. Worth it just for the tip about irb and assigning variable with an underscore!
Packed full of win! The underscore in IRB hint alone was well worth the download, but being able to get rid of several lines of complex code using searchlogic.... excellent episode. Keep it up.
Nice, but the better way is to use ThinkingSphinx with sphinx_scope.
Is there any way to get the logger to run automatically when script/console is started up? I can't imagine not wanting it active. Cheers.
One thing I noticed when using searchlogic is the class of the return value is not what you expect: -
1. User.find_by_login('bob').class -> returns User
2. User.login_equals('bob').class -> returns ActiveRecord::NamedScope::Scope
This is an important distinction as you cannot call methods such as .destroy on the second example.
@jDeppen: go ahead and use SearchLogic for the front-end search, but make sure the controller scrubs out any values in the search hash that you don't want there.
http://gist.github.com/176481
This way, you can even define defaults for the search.
Thanks, Ryan! Great episode.
I was surprised that there was no mention SearchLogic's interoperability with will_paginate. Paginating search seems to be one of the big hurdles newbie Rails developers tackle.
All one needs to do is call the paginate method on the search, thus:
@search = Product.search(params[:search])
@products = @search.paginate( :page => params[:page] )
I want this locally on my machine.
Product.name_not_like("Video").price_gt(5).price_lt(200)
Produces
SELECT * FROM `products` WHERE (products.price < 200)
Hi Ryan!
Great Screencast. I use Searchlogic in my hobby project. But currently I have a little problem with Searchlogic.
For example:
1: User.login_or_email_like("foobar")
2: User.search(:login_or_email_like => "foobar")
Correct me if I am wrong but these two should have the same result.
The former one works fine, but the latter one does not it returns all Users.
Currently I read something about cells (http://cells.rubyforge.org/b) in RailsWay. Did you know cells?
Hear you tomorrow
@hartwig,
I have the same issue. Any ideas anyone? Maybe we're looking at a gem conflict?
I looked at the code and i believe that the method which is responsible for processing the "or" conditions, don't get called if you use the User.search ... form.
But I am not sure.
I am still learning the "meta-programming" thing in ruby. But I believe Dave Thomas or Paolo Perrotta sad there is no such thing, its just programming ;-)
I don't have a github account yet, but can somebody post there a comment about the searchlogic issue.
@ryan Your videos are great. They help me to forget php ;-)
If you want to offer your users a simple search box instead of a complex form to search your models, check out scoped_search: http://github.com/wvanbergen/scoped_search
class Model < ActiveRecord::Base
scoped_search :on =>[:name, :description, :created]
end
Model.search_for(params[:q]).paginate(...)
This will work with queries like:
- keyword1 keyword2 keyword3
- (a | b) & created > 2009-01-01
- name = "Willem van Bergen"
At the end of the video Ryan mentions the form_for method should not be used for public facing pages. He says to setup custom forms in those situations. What exactly is meant by that? Does that mean to use form_tag to build the form? If so, how do I do this using multiple scopes?
@Tim Gossett - You need to post what you said about getting will_paginate to work with searchlogic in the forums. This is the only place I found that solution... even though it's a simple easy one some people don't think of doing that. Thanks sooo much!!
Hi Ryan,
How did you get the query executed to be displayed on the console? Another irb trick? Loved the Hirb hint!
Cheers,
Aditya
@hartwig @Ryan @eric,
i have the same problem with the or-condition. i.e. User.search(:firstname_or_lastname_like => "foo") is not working. In the console i get the notice: #<Searchlogic::Search:0x34503f0 @conditions={:firstname_like_or_lastname_like=>false}, @current_scope=nil, @klass=User(id: integer, ....
Has anyone found a solution to this problem?
Great post thought, Ryan. As always.
Hi Ryan,
I have two text_field_tag in my view.
In the first text_field_tag, I can enter name, category or description.
In the second text_field_tag, I can enter city, state or zip.
Right now I am using form_tag.
How can I use form_for to use order in above situation?
Is it possible to pass a SQL limit?
Is it possible to do sorting on two columns like:
ascend_by_last_name.ascend_by_first_name?
It seems searchlogic ignores the second ordering command.
Does this even work with virtual attributes?
I keep getting an error "undefined method `age_greater_than' for #<Class:0x48fff80>" where age is a virtual attribute.
Anyone?
Hi, ryan.
This screencast's link broken please check.
Thanks.
First of all, thanks for the awesome screencast. I just came across this site recently and it's been an amazing resource so far.
But I'm having some trouble. I've been able to implement the search form on my model's index.html.erb file, but putting it in the application.html.erb file to act as a global search accessible from any page results in me getting whiny_nil errors all over the place.
My app is a listing of bars and their respective specials. So the search works great on the index page where all the bars are listed. I can search just fine, everything works as expected from that side of things.
But when I click a link to see additional details about the bar, THAT is when I get the whiny_nil.
I just don't know what to do or why it doesn't work. I can't seem to find anything online about implementing a global search using SearchLogic. :(
Nevermind! I figured it out...global search form required a global variable. :)
Have modifiers been removed from version 2 of Searchlogic? If not how do you use them, all I can find are old out-dated examples from version 1.x
@Austin Ginder try to use will_paginate for it. I think it's the only way for now.
hey, Ryan,
Searchlogic V2 is out.
Is this for V2? If not, could you please show one for V2?
Would be nice to see how you go abouts setting up routing for the search resource :) thanks
I've been able to implement the search form on my model's index.html.erb file
hi ryan
great post. I managed to get searchlogic 2.3 working for me. When I use will_paginate, the only thing that breaks is the "order".
When i load my search results page, i seem to get an error indicating "order" is not defined.
I later found out that to get ordering to work again, i need to be able to generate the same url (with params) and append the order clause to it.
1) how do i do it?
2) with searchlogic 2.3.+ and will_paginate, how can we still maintain using "order" in the view as per your tute?
thnaks for this great video.
I am facing a problem with will_paginate, if i want to use pagination along with <%= order %>, it is not working and giving me this error
undefined method `order' for #<WillPaginate::Collection:0xb6f1fa5c>
Thanks
Great Railscast as usual! Digging a bit further, i found using named scopes essential...
hi there,
Like Ritesh who posted on Dec 16, 2009 at 08:22 ,
I am also facing a problem with the undefined method "order".
Please help, Ryan?
I get a runtime error when i try to access the search form page. I can search fine in the script/console but when i got to my search page i get " Showing app/views/groups/search.html.erb where line #1 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"
I cant figure out what is causing this problem
I tried # OR part in the controller and now i get "wrong number of arguments (1 for 2)"
I dont get what i keep doing wrong
I'm really excited about implementing search with this Railscast, but I keep getting an error I can't find help on. When I render the search form, I keep getting:
undefined method `nil_class_path' for #<ActionView::Base:0x3775a94>
Any ideas?
Is it possible to have an index with just the search form and when a user "submits" then the results are printed below? Currently I have an unfiltered list that becomes smaller upon "Submit". Also I can create dropdowns using searchlogic, but they don't render results (filter my list) when I hit submit.
I am a newbie, so bear with me.
My newly create site using searchlogic is here: http://grants.firelightfoundation.org
Is it possible to use searchlogic in rails 3? If not, what's the best other solution? Thanks
It couldn't have been done better. From a noob point of view, its a gem. Though my needs didn't exactly fit with the example, a peek at the documentation gave me what i wanted. Nice work!
Hey Guys,
Have been tinkering with thinking sphinx but that might be overkill on the project i am currently working on. The only reservation I have about searchlogic is that the owner of the project wants clean urls, searchlogic doesnt seem to have this on first look. Any ideas for cleaning up the urls?
Stu
I can not get searchlogic to work when using a has_many through model. Is it supposed to? I get method_missing when I try to search for something in the has_many table.
Thanks,
Ryan
In response to questions about Rails 3 - It appears (from looking on the the github page issues section) that searchlogic is pretty heavily tied to ActiveRecord 2 and not trivial to switch over. There is a port in progress at railsdog/searchlogic currently in it's 3rd or fourth release candidate. I haven't been able to get it to work yet, but it's worth checking out.
I tried a very simple example but I get the following error:
ArgumentError in Admin/usersController#index
wrong number of arguments (1 for 2)
## UsersController
def index
@search = User.search(params[:search])
@users = @search.paginate( :page => params[:page] )
end
## index.html.erb
<% form_for @search do |f| %>
<%= f.label :name_like, "Name" %>
<%= f.text_field :name_like %>
<%= f.submit "Submit" %>
<% end %>
I have no idea what this error is. Can anyone help?
Thanks,
so, is searchlogic working with Rails 3?
Oops... Sorry... Chirstopher Small isn't a spammer.... clicked one too much... Apparently searchlogic still isn't Rails3 ready :( Maybe you should put a big warning on top of this post (and as well for all others plugins/gems not compatible with rails3)
Would be really helpful if searchlogic would be ported to rails 3. I want to upgrade a rails 2.3 project to rails 3, would hate to have to remove searchlogic.
Oh well.. that's a problem with most rails plugins/gems - they stop being upgraded after a while and when you have an older project that uses them then you are out of luck.
You might want to look into Ernie Miller's Ransack gem https://github.com/ernie/ransack
I second the warning aboiut Searchlogic not working with Rails 3. Took me a while to figure this one out, and I had gotten all excited about using it too :(
It produces this error:
error [long path] 'alias_method': undefined method
merge_joins' for class
Class' (NameError)Is it possible to do sorting on two columns like:
ascend_by_last_name.ascend_by_first_name?