ADWR Question: Page 171


#1

I am a complete newbie to Ruby and Rails. I purchased the Agile Dev with
Rails book this weekend, and am making my way through it.

I’m in the testing chapter, and trying to complete the “exercise for the
reader” by implementing search on the website.

According to my functional test (identical to the book), I have a
working search controller. I also got a results.rhtml page written, and
can load it up with information through the browser.

My problem is this. I am trying to create a search page that lets the
user enter the terms to search for, then invoke the search action on the
search controller and display what matches. I have an index.rhtml that
has a simple form (one text field) and a submit button to the search
action. This seems to work, and I wind up on the results page.

However, the value I type into the text field does not appear to be
submitted through the form to the action. I always get all books
displayed on the results page (I also seem to have the flash statement
[Found 3 products] showing up on the index, when it is not expected).

If someone could point me in the direction of my error, I would
appreciate it.

Thanks,
Ken S.

Here is what I have written:

index.rhtml:
<% @page_title = “Search PragProg Online Store” %>

<%= start_form_tag({:action => “search”}) %>

Enter search terms:
<%= text_field(nil, “query”) %>

<%= submit_tag(" Search ") %>

<%= end_form_tag %>

results.rhtml:
<% @page_title = “Search Results”%>

<% for product in @products %>
    <h3><%=h product.title %></h3>
    <%= product.description %>
    <span class="catalogprice"><%= fmt_price(product.price) 

%>
<%= link_to ‘Add to Cart’,
{:controller => ‘store’,
:action => ‘add_to_cart’, :id => product },
:class => ‘addtocart’ %>


 

<% end %>

<%= link_to “Show my cart”, {:controller => “store”, :action =>
“display_cart”} %>

search_controller.rb
class SearchController < ApplicationController

layout “store”

def index
end

def search
@products = Product.search(params[:query])
flash[:notice] = “Found #{@products.size} product(s).”
render “search/results”
end
end


#2

kscott wrote:

@products = Product.search(params[:query])

shouldn’t that be:

@products = Product.find(params[:query])


#3

On 11/23/05, Ken S. removed_email_address@domain.invalid wrote:

def search
@products = Product.search(params[:query])
flash[:notice] = “Found #{@products.size} product(s).”
render “search/results”
end
end

Does the method Product.search exist?


#4

On 11/23/05, Thomas M. removed_email_address@domain.invalid wrote:

kscott wrote:

@products = Product.search(params[:query])

shouldn’t that be:

@products = Product.find(params[:query])

Unless the ActiveRecord.find method changed a lot recently, I think
that method expects to be passed an ID for one of the records. (so
you can’t type in a product name)

What you probably want is something like
Product.find_by_name(params[:query]), but that only works if you have
an exact match.


#5

Got it figured out. Joe is correct, to use find, you have to give it an
id.

But that at least got me an error that dumped the params object being
passed in.

The working line is this:
Product.search(params[:search][:query]

I set up the query field inside of a search object, but didn’t know how
to reference it in the controller. I think I need to read the PickAxe
book some more, and get used to referencing data structures in Ruby.

Thank you all for the hints that got me to the right place. I feel so
accomplished, adding a new capability to the web app that I didn’t type
out of the book. Maybe I can learn this stuff!

I still have the problem where the flash object is not being cleared out
after it is displayed. What I mean, is that in my search/results view, I
print the flash[:notice]. If I then go to the store index, I still have
the same message at the top.

Any ideas?

joevandyk wrote:

On 11/23/05, Thomas M. removed_email_address@domain.invalid wrote:

kscott wrote:

@products = Product.search(params[:query])

shouldn’t that be:

@products = Product.find(params[:query])

Unless the ActiveRecord.find method changed a lot recently, I think
that method expects to be passed an ID for one of the records. (so
you can’t type in a product name)

What you probably want is something like
Product.find_by_name(params[:query]), but that only works if you have
an exact match.