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!
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
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
You are close with your check on #users? but it should be:
<% if !#users.empty? %>
<% #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.
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 %>
Related
I'm trying to make a search form with Ruby on Rails. Part of it is successful and part of it is not. If i type in a part of the usernames of emails I have registered, results come back. But when I type in the full username of a user, no results come back. Here is my user.rb file:
def self.search(search)
where("username LIKE ?", "%#{search}%")
where("email LIKE ?", "%#{search}%")
end
My search_controller.rb:
def index
#users = User.all
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
end
And finally my view:
<%= form_tag(search_path, :method => 'get', id: 'search-form') do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Users" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% if params[:search].present? %>
<% if #users.present? %>
<h1><li>Search Results for: "<%= params[:search] %>":</li></h1>
<% #users.each do |user| %>
<li><%= user.username %></li>
<li><%= user.email %></li>
<br />
<% end %>
<% else %>
<p>There are no users with the term(s) <%= params[:search] %>.</p>
<% end %>
<% else %>
<title>Search Users</title>
<% end %>
Your method only returns the result of the second where. To fix this combine both queries into one:
def self.search(search)
where('username LIKE :query OR email LIKE :query', { query: "%#{search}%" })
end
I get a "TypeError in Activities#member - can't convert Symbol into Integer"
I would say that 95% of my records work fine but I have a couple that keep tripping this error. Where do I start to look at this problem.
Here is the code I am working with:
.html.erb page
<div id="listing-gallery">
<ul id="listing-slides">
<% listing.slides.each_with_index do |slide, i| %>
<%= content_tag :li, :id => "slide#{i}", :class => (i == 0) ? "active" : "" do %>
<%= image_tag slide[:large] %>
<% end %>
<% end %>
</ul>
<ul id="listing-slide-thumbs">
<% if listing.slides.count > 1 %>
<% listing.slides.each_with_index do |slide, i| %>
<%= content_tag :li, :class => (((i+1)%4 == 0) ? "last" : "") do %>
<%= content_tag :a, :href => "#slide#{i}" do %>
<span class="hover"></span>
<%= image_tag slide[:thumb] %>
<% end %>
<% end %>
<% end %>
<% end %>
</ul>
.activities_controller.rb
def member
# Assign attrs if venue exists
if #member.nil? || #member.venue.nil?
redirect_to activities_path
else
if #member.venue.attrs.count > 0
# match_by_type can be found in the ApplicationHelper
#attrs = match_by_type #member.venue.attrs
else
#attrs = nil
end
unless #member.venue.nil?
unless #member.venue.attrs.nil?
#member_rentals = #member.venue.attrs.all_by_type("Rentals")
end
end
end
end
Where do I go from here?
see <%= image_tag slide[:large] %> and <%= image_tag slide[:thumb] %>
what image attribute for slide?
If image is attribute for slide, I think such as :
<%= image_tag slide.image.url(:large) %>
or if usinng carrierwave
<%= image_tag slide.image_url(:large).to_s %>
By the way, I don't see listing.slides on action member
on my users index page I am trying to have a search engine at the top so that you can search a user by email instead of scanning through the whole list. However, I am getting the error:
undefined method 'total_pages'
when I search any term.
Can anyone help? Thanks!
users/index.html.erb
<h1>All users</h1>
<%= form_tag users_path, :method => "get" do %>
<%= label_tag(:search, "Search for user by email:") %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<%= will_paginate #users %>
<br>
<% #users.each do |user| %>
<div>
<%= link_to (image_tag user.profilepic? ? user.profilepic : "questionmark.png", :size => "50x50"), user_path(user) %>
<%= link_to user.name, user_path(user) %> (<%= user.email %>)
<% unless current_user.friends.include?(user) || current_user == user %>
<span class="floatright"><%= link_to "Add friend", user_friends_path(:user_id => current_user.id, :friend_id => user.id), :method => :post %></span>
<% end %>
<% if current_user.friends.include?(user) %>
<span class="floatright"><%= link_to "Remove friend", user_friends_path(:user_id => current_user.id, :friend_id => user.id), :method => :delete, :confirm => "Are you sure you want to remove #{user.name} from your friends?" %></span>
<% end %>
</div>
<% end %>
users controller
def index
if params[:search]
#users = User.search(params[:search])
else
#users = User.order("email").page(params[:page]).per_page(10)
end
end
user model
def self.search(search)
find(:all, :conditions => ['email LIKE ?', "%#{search}%"])
end
You're not calling a pagination method in #users = User.search(params[:search]). Try adding the .page(params[:page]).per_page(10) and see if that works.
UPDATE:
Sorry, I forgot .find returns an array and not a relation. Change your search method to this:
def self.search(search)
where('email LIKE ?', "%#{search}%")
end
I'm having trouble showing my view correctly. I have this as my code right now:
<% for store in #stores %>
<% store.name %>
<% #stores.products.each do |p| %>
<% p.name %>
<% end %>
<% end %>
def index
#stores = Store.paginate(:page => params[:page], :per_page => 20)
end
But end up with the error:
undefined method `products'
I'm trying to show a store and then all of its products, repeating this on the same page as much as possible e.g:
Store1
Product1
Product2
Store2
Product1
Product2
Product3
Product4
How can I do this?
Instead of <% #stores.products.each do |p| %> I think you mean <% store.products.each do |p| %>:
Also, do you not mean to have <%= on the store.name and p.name lines?
<% for store in #stores %>
<%= store.name %>
<% store.products.each do |p| %>
<%= p.name %>
<% end %>
<% end %>
Shouldn't that be store.products inside the loop, where you're accessing store?
<% for store in #stores %>
<%= store.name %>
<% store.products.each do |p| %>
<%= p.name %>
<% end %>
<% end %>
And = is added to the output lines. <%=
I'm sure it's a simply issue due to me not fully understanding how bits fit together in Rails...
I've followed the rails cast but I'm having trouble implementing it into my app (I've had it working stand-alone).
The error I get is
undefined method `nearbys'
Here's what I've got:
user.rb
geocoded_by :full_address
after_validation :geocode
def full_address
[address1, address2, address3, city, country, postcode].compact.join(', ')
end
users_controller.rb
def index
#title = "All users"
if params[:search].present?
#users = User.near(params[:search], 50, :order => :distance)
else
#users = User.all
end
end
index.html.erb
<h3>Nearby locations</h3>
<ul>
<% for user in #users.nearbys(10) %>
<li><%= link_to user.address1, user %> (<%= user.distance.round(2) %> miles)</li>
<% end %>
</ul>
_sidebar.html.erb
<%= form_tag users_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search Near", :name => nil %>
</p>
<% end %>
Thanks
If I comment out the .nearbys
<% for user in #users#.nearbys(10) %>
<li><%= link_to user.latitude, user %> (<%= user.distance.round(2) %> miles)</li>
<% end %>
The search works. Could this be a problem with the install of geocoder?
The function nearbys is a function on your model, not on a collection of models. The variable #users contains a collection of User models. You need to call the function on a single model instance, for example for each user in #users.
As an example, but not sure if you really want this:
<% #users.each do |user| %>
<% user.nearbys(10).each do |near_user| %>
<li><%= link_to near_user.latitude, near_user %> (<%= near_user.distance.round(2) %> miles)</li>
<% end %>
<% end %>
(Note that I also changed the for user in #users to use #users.each do |user|, which is more "Rubyish".)