Basic search, quick question

Hi, I know there are other threads about this topic, but I’ve checked
and none seem to help my problem.

I’m trying to get a simple search to work on my Rails app, but I get a
“Couldn’t find Recipe without an ID” error when I search. Here’s what I
have:

list.rhtml

<%= start_form_tag :action => ‘find_recipes’ %>

<%= submit_tag ‘Search’ %>
<%= end_form_tag %>

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
redirect_to :action => ‘results’
end

def results
@recipe = Recipe.find(params[:title])
end

results.rhtml

<%= @recipe.value %>

Is it something obvious and dumb? Also, how do I get it to search
several fields at the same time?

Thanks!

Hi –

On Fri, 17 Nov 2006, Dave A. wrote:

<%= start_form_tag :action => ‘find_recipes’ %>
end

def results
@recipe = Recipe.find(params[:title])

It doesn’t look like you’ve set params[:title] anywhere. I also
suspect you don’t really want :title here.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

in your find_recipies controller you’re looking for a recipe based on
params[:search] (the value submitted in the text box), and setting it
to the variable @recipe. But then you redirect to the results method
which then runs find again, this time based on params[:title] which
doesn’t exist, and then storing that to @recipe, which is then
displayed.

The simple fix here is to drop your results method altogether

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
end

find_recipes.rhtml

<%= @recipe.value %>

(by the way, you can also use the text_field helper instead of the html
input tag in your view.rhtml).

Hi, great, that makes much more sense to me. I’m still getting an error
(undefined method ‘value’). What do I have to do to make .value work?

Also, if I want it to search more than titles, like also descriptions,
how would I add that in there?

Thanks for all the help so far; I’m learning a lot.

François Montel wrote:

in your find_recipies controller you’re looking for a recipe based on
params[:search] (the value submitted in the text box), and setting it
to the variable @recipe. But then you redirect to the results method
which then runs find again, this time based on params[:title] which
doesn’t exist, and then storing that to @recipe, which is then
displayed.

The simple fix here is to drop your results method altogether

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
end

find_recipes.rhtml

<%= @recipe.value %>

(by the way, you can also use the text_field helper instead of the html
input tag in your view.rhtml).

I assume this is the code you have running now:

list.rhtml

<%= start_form_tag :action => ‘find_recipes’ %>

<%= submit_tag ‘Search’ %>
<%= end_form_tag %>

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
end

results.rhtml

<%= @recipe.value %>

So the key thing to note here is that Recipe.find(:all, …) returns an
array of Recipe objects. So your instance variable would properly be
named
@recipes. In your results.rhtml, you’d want to do something like

<% @recipes.each do |recipe| %>
<%= recipe.value %>
<% end %>

If you simply want the same search field to search both title and
author,
then you’d have to do something like :

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ? or author
LIKE
?’,
“%#{params[:search]}%”, “%#{params[:search]%” ]
end

But that is getting messy, and is not quite DRY. Though I haven’t used
it
myself, I hear good things about the acts_as_ferret extension.

Good luck.

I still haven’t figured out how to get the search results to display in
the view file find_recipes.html. I can’t seem to get around the
“undefined method ‘value’” error.

I’m searching in the title, but I want to bring up more than just the
title in the search results (things like the author). Is that much
harder to implement?

Thanks!

Dave A. wrote:

Hi, great, that makes much more sense to me. I’m still getting an error
(undefined method ‘value’). What do I have to do to make .value work?

Also, if I want it to search more than titles, like also descriptions,
how would I add that in there?

Thanks for all the help so far; I’m learning a lot.

François Montel wrote:

in your find_recipies controller you’re looking for a recipe based on
params[:search] (the value submitted in the text box), and setting it
to the variable @recipe. But then you redirect to the results method
which then runs find again, this time based on params[:title] which
doesn’t exist, and then storing that to @recipe, which is then
displayed.

The simple fix here is to drop your results method altogether

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
end

find_recipes.rhtml

<%= @recipe.value %>

(by the way, you can also use the text_field helper instead of the html
input tag in your view.rhtml).

I apologize,
This was a cut-and-paste error on my part. Make sure that in your
controller, you are setting the @recipes variable (not the singular
@recipe). So the controller should be something like:

def find_recipes

the @recipes will be an array (possibly empty) of Recipe models

@recipes = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%”]
end

Your view should be something like :

<% @recipes.each do |recipe| %>
<%= recipe.value %>
<% end %>

Note that the @recipes in the view is set by the controller. I assume
that
the error about calling nil.each you encountered earlier is because in
the
controller, you set @recipe, and in the view, you used @recipes.

Yes, thank you so much! That’s it! :slight_smile:

Jimmy Kittiyachavalit wrote:

Thanks for your help, but I still can’t get it to work. :frowning:

When I try to do it just as you have it, I get an error trying to
evaluate nil.each, which makes me think that Rails couldn’t find
anything in the @recipes variable in results.rhtml. Does this have to
match @recipe = Recipe.find… in the controller?

When I change @recipes to @recipe in results.rhtml, it tells me that it
doesn’t recognize the method “value”. Is this a standard part of Ruby,
because I don’t mention it anywhere in the controller.

Sorry for all the questions, I want to make it work and understand how
it works at the same time. Your explanation before was great!

Thanks again,

Dave

Jimmy Kittiyachavalit wrote:

I assume this is the code you have running now:

list.rhtml

<%= start_form_tag :action => ‘find_recipes’ %>

<%= submit_tag ‘Search’ %>
<%= end_form_tag %>

recipes_controller.rb

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ?’,
“%#{params[:search]}%” ]
end

results.rhtml

<%= @recipe.value %>

So the key thing to note here is that Recipe.find(:all, …) returns an
array of Recipe objects. So your instance variable would properly be
named
@recipes. In your results.rhtml, you’d want to do something like

<% @recipes.each do |recipe| %>
<%= recipe.value %>
<% end %>

If you simply want the same search field to search both title and
author,
then you’d have to do something like :

def find_recipes
@recipe = Recipe.find :all, :conditions => [‘title LIKE ? or author
LIKE
?’,
“%#{params[:search]}%”, “%#{params[:search]%” ]
end

But that is getting messy, and is not quite DRY. Though I haven’t used
it
myself, I hear good things about the acts_as_ferret extension.

Good luck.