0

I'm using Rails 3, mac os mountain lion and Ruby 1.9.3

So i have this object called object1. I built a search function for it and it works properly:

def self.search(search)
  search_condition = "%" + search + "%"
  if search
    find(:all, :conditions => ['name LIKE ?', search_condition])
  else
    find(:all)
  end
end

Now I want to use this in object2. So in object2 controller I wrote:

def search
  @results = Object1.search(params[:search])
end

and in the view:

= form_tag object2_path, :method => 'get' do
  #{text_field_tag :search, params[:search], :id => 'search_field'}
  #{submit_tag "Search", :name => nil}

- for result in @results
  %li
    = result.name

But for some reason the @results return nil. What's wrong with what I'm doing? Thanks a lot.

jvnill
  • 29,479
  • 4
  • 83
  • 86
Aldrin Dela Cruz
  • 205
  • 1
  • 4
  • 15
  • `scope :search, ->(name) { where("name LIKE ?", name) }` – itsnikolay Feb 22 '13 at 10:20
  • 1
    `@results` is declared in the search action, is this the action that processed the request? if your view is not rendered after processing the search action, you'll have `@results` variable to use in the view. – jvnill Feb 22 '13 at 10:24

3 Answers3

0

Your code to do the search is correct, that is not the problem. In your view you write:

= form_tag object2_path, :method => 'get' do

Unless you took special measure, this will hit the index method of your object2-controller. So you could fix this by changing your index method to search if there is a params[:search] defined.

Or change the path of the form to go to the search-path and make sure it renders the correct view.

HTH.

nathanvda
  • 49,707
  • 13
  • 117
  • 139
0

Have you made sure the search method is defined in routes.rb? If you didn't it will default to the show action, and there @search is probably not set.

You also might want to change the URL of the form:

form_tag object2_path, :method => 'get' do

to

form_tag search_object2_path, :method => 'get' do

Your controller codes looks fine to me.

Vikko
  • 1,396
  • 10
  • 23
-1

Always put the common code in application helper;

Application helper:

module ApplicationHelper
  def search(search)
    search_condition = "%" + search + "%"
      if search
        find(:all, :conditions => ['name LIKE ?', search_condition])
      else
        find(:all)
      end
  end
end

Now you can call the method from your controllers like:

search(params[:search])

If you want to make sure how you can call helper methods from controllers check this SO post.

Community
  • 1
  • 1
sjain
  • 23,126
  • 28
  • 107
  • 185
  • 2
    Helpers are intended for view code. This belongs in the model. Source: Pretty much everything ever written about Rails helpers. – Fareesh Vijayarangam Feb 22 '13 at 10:23
  • This belongs to controller actually. I already updated according to the question. You can't say that they are intended for views only. – sjain Feb 22 '13 at 10:26
  • I agree with Fareesh. Given this particular function, i say this belongs to the model and not a helper. helpers are supposed to work with the view and not connect to the database. – jvnill Feb 22 '13 at 11:07
  • @jvnill- In contrast to the question only, I updated the post by calling the method in a controller as the questioner is calling from there. Otherwise before that, I have kept it in a model. – sjain Feb 22 '13 at 11:27
  • Aaarrrgghh this is the worst suggestion ever. `ApplicationHelper` is for view-helpers. In this case the `search` method already is defined where it belongs: on the model. Why propose to move it to a helper? It WILL NOT WORK! The method `find` is not defined in the helper context. It only works on a ActiveRecord model. – nathanvda Feb 22 '13 at 15:17
  • No, the purpose to define it in a helper is because this method is called multiple times by many objects. So it should belong to a common place to increase the re-usability. – sjain Feb 22 '13 at 15:25