benoitr
benoitr

Reputation: 6105

Ruby/Rails Conditional search method (if ... else "no results found")

Here is the code of a "simple search form" (thanks to jordinl) which I try to improve. I would like to add the case if there is no match found.

So, there is the view (views/users/index.html.erb)

<% form_tag users_path, :method => 'get' do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", :name => nil %>
<% end %>

<% @users.each do |user| %>  
  <p><%= link_to "#{user.name}", user %></p>
.
.
.
<% end %>

The controller ( users_controller.rb)

def index
  @users = User.search(params[:search])
end

and the method in user model:

def self.search(search)
  search.blank? ? [] : all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end

I tried the following:

def self.search(search)
  if search.to_s.size < 1
    []
  else
    if  @users.size > 0
      all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
    else
      render :text => "No result found"
    end
  end
end

reporting the following error: "You have a nil object when you didn't expect it!..." (no instance in the array). Then, I tried to add

<% if @users? %>
  <% @users.each do |user| %>
.
.
.

In the view. But it doesn't work either.

I would be pleased to understand why I'm wrong on this. Thank you!

Upvotes: 0

Views: 7005

Answers (4)

sled
sled

Reputation: 14635

you can't render in your model.

In your view:

<% form_tag users_path, :method => 'get' do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", :name => nil %>
<% end %>

<% if @users.empty? %>
  No records found!
<% else %>
  <% @users.each do |user| %>  
    <p><%= link_to "#{user.name}", user %></p>
  <% end %>
<% end %>

In your model:

def self.search(search)
  search.blank? ? [] : all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end

Upvotes: 2

tadman
tadman

Reputation: 211670

You're on the right track. Try this:

<% if (@users) %>
  <% if (@users.empty?) %>
    <p>No users found.</p>
  <% else %>
    <% @users.each do |user| %>  
      <p><%= link_to "#{user.name}", user %></p>
    <% end %>
  <% end %>
<% else %>
   <p>Use the search form to search for stuff.</p>
<% end %>

Change your search method to only return something if searching was used:

def self.search(search)
  search.present? and all(:conditions => [ 'name LIKE ?', "%#{search.strip}%" ])
end

Upvotes: 3

Yannis
Yannis

Reputation: 5426

Your self.search method should return an array, either full or empty. Try:

in you model

def self.search
  self.all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end

and in your view

  <% if @users? %>
    <% @users.each do |user| %>
      …
    <% end %>
  <% else %>
    No result
  <% end %>

Upvotes: 1

Shadwell
Shadwell

Reputation: 34774

You are close with your check on @users? but it should be:

<% if [email protected]? %>
  <% @users.each do |user| %>
    ...
  <% end %>
<% else %>
  No users found.
<% end %>

This will work with your original self.search implementation which, correctly, is used just to find users and does not need to worry about reporting if none are found.

Upvotes: 1

Related Questions