Rails: Display database query on HTML page, ActiveRecord - ruby-on-rails

I am trying to create a search form for my rails app, the user enters a query and based off that query, I want them to see a list of links associated with that query (these links come from my 'links' table). I created the HTML form and it has the user enter a query. I use this query
<%= form_tag links_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "search", :name => nil %>
</p>
<% end %>
In my controller for the links table, I have an if statement that checks what the user has entered and it assigns Link.where('title LIKE ?', '%{#params[:search]}%') to #links. and then converts it to an array (.to_a)
Here is the statement in the index action:
def index
#links = Link.all
if params[:search]
##links = Link.find(:all, :conditions => ['title LIKE ?', '%{#params[:search]}%'])
#links = Link.where('title LIKE ?', '%{#params[:search]}%')
#links.to_a
end
end
In my index.html.erb I would like to display the result. I used <%= #links %> however, it displays the ActiveRecord: #<Link::ActiveRecord_Relation:0x0000000d5c69f0>
How could I convert the query result ActiveRecord into an array, so then I could be able to index it?
Thanks.

Don't EVER EVER EVER EVER use
#links = Link.where('title LIKE ?', '%{#params[:search]}%')
this is a security issue. Check http://railscasts.com/episodes/25-sql-injection.
In order to see all likes as an output just simply do
#links = Link.where('title LIKE ?', params[:search]')
and in Views do
<%= #links.to_a %>
That should help :)

You need to assigns #links like this:
#links = #links.to_a
By the way, if you want render link one-by-one using something like #links.each, you do not need to convert #links to array.

Related

search form in nav bar doesn't render anything

I have a search form in my nav bar
<%= simple_form_for :query, url: clients_products_path, method: :get, wrapper: :inline_form, html: {class: 'form-inline'} do |f| %>
<%= f.input :keyword, placeholder: "Recherche" %>
<%= f.submit "Valider" %>
<% end %>
In my product_controller.rb
class Clients::ProductsController < ApplicationController
def index
filter_products if params[:query].present?
#products ||= Product.all
end
private
def filter_products
return if params[:query].blank?
#products = Product.where('lower(title) LIKE ?', params[:query][:keyword]) if params[:query][:keyword].present?
end
end
My query seems to be correct as I can find product in the rails console.
but it doesn't display anything in the product#index...
Where am I wrong?
update
All products are well displayed, and everything disapear when I make a query
clients/products/index.html.erb
<% #products.each do |product| %>
<%= link_to clients_product_path(product) do %>
<%= image_tag(product.attachments.first.url) %>
<%= product.title %>
<%= product.price %>
<% end %>
<% end %>
here is the result
http://localhost:3000/clients/products?utf8=%E2%9C%93&query%5Bkeyword%5D=jean&commit=Valider
I believe your issue lies here:
#products = Product.where('lower(title) LIKE ?', params[:query][:keyword])
You need to either prepend, append or wrap your query with %. For example:
#products = Product.where('lower(title) LIKE ?', "%#{params[:query][:keyword]}%")
# Think it's the above, though could be the following:
# #products = Product.where('lower(title) LIKE "%?%"', params[:query][:keyword])
If you have a read on SQL's LIKE operator, the % operates something like a wildcard. Without these, you're searching for an exact match, rather than a phrase contained within the title. Docs are here.
Give that a shot and let me know how you get on.
First of all you are checking params[:query] twice(once when calling filter_products and second time in that function)
And their is something wrong with you filter_products function.
When you do #products ||= Product.all you get blank ActiveRecordRelation if query returns empty relation. In other words #products will always be blank if query[:keyword] doesn't match the title.
Try changing your index function to:
def index
#products = Product.where('lower(title) LIKE %?%', params[:query][:keyword].downcase) if params[:query][:keyword].present?
puts #products
#products ||= Product.all
end
If it still returns blank, then try to print #products variable.

ActiveRecord StatementInvalid (Ruby on Rails)

So I keep getting the following error when trying to search:
ActiveRecord::StatementInvalid in Clients#search
SQLite3::SQLException: no such column: client: SELECT COUNT(*) FROM "clients" WHERE (client = '')
client.rb (model)
def self.simple_search(search_string)
self.where("client = ?", search_string)
end
index.html.erb
<div id="client-search">
<%= render(:partial=>'/search',:locals=>
{ :my_path => "/clients/search" })%>
</div>
clients_controller
def search
#clients = Client.simple_search(params[:search_string])
render :action => "index"
end
_search.html.erb
<%= form_tag my_path do %>
<h6>Search Customer</h6>
<%= text_field_tag :search_string %>
<%= submit_tag 'Search' %>
<% end %>
Any chance someone could help me with how I can get around this error please?
Is there actually a column named client in the clients table?
By the way, if there is then you could use:
def self.simple_search(search_string)
self.where(client:, search_string)
end
You don't have a column named client on your clients table. Maybe you need to be searching name or some other attribute?
def self.simple_search(search_string)
self.where("{put the column name you want to be searching here} = ?", search_string)
end
But in most cases you will need to do something like:
self.where("{put the column name you want to be searching here} LIKE '%?%'", search_string)
And to take it further, just make it a scope on your model instead of method.

Creating site-wide search in a Rails app

I'm trying to create a search form that retrieves results based on a user's query for a restaurant's name. So far I've setup its route, controller, and index view.
routes.rb
resources :search, :only => [:index]
search_controller.rb
class SearchController < ApplicationController
def index
if params[:query].present?
#restaurants = Restaurant.search(params[:query])
else
#restaurants = Restaurant.all
end
end
end
search/index.html.erb
<% #restaurants.each do |restaurant| %>
<%= restaurant.name %>
<% end %>
Here is how the search for is setup:
layouts/_header.html.erb
<%= form_for search_index_path, method: :get do |f| %>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
<% end %>
Right now I'm running into two problems. The first being that if I enter a query and submit, the page doesn't go to the index page. All it does is append the query to the current page I'm on:
localhot:3000/restaurant?utf8=✓&query=pizza
Second is that I'm getting every restaurant in my db on the index page (as expected). Is there a way that I can make it so the page is blank for anything other than on search requests?
Question 1
Use form_tag instead of form_for, since the latter is used to handle specific model objects and this is not the case.
Question 2
You can achieve that by:
if params[:query].present?
#restaurants = Restaurant.search(params[:query])
else
#restaurants = [] # or Restaurant.none if you need a chainable scope
end

adding search functionality to a paginated page in RoR

Here is the scenario:
I have a table which renders a list of groups (id,title,description,etc) like below which is paginated, it also has a search form:
<div id="navigation" style="background:white;border:1px outset cadetblue;">
<p>
<% form_tag groups_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
</p>
</div>
<table>
.....
</table>
<%= paginate #groups %>
In my groups_controller.rb I have:
#groups = Group.search(params[:search])
#groups = Group.order("id").page(params[:page]).per(15)
which doesn't seem to be working. The pagination works but when I click
the search button it doesn't do anything.
The search function is implemented in the group.rb model:
def self.search(search)
if search
find(:all, :conditions => ['description LIKE ?', "%#{search}%"])
else
find(:all)
end
end
How do I solve this, how do I make my search form work and return results in a paginated way!
Here is the ultimate answer to this post. All the original poster needed to do was this:
#groups = Group.where("description LIKE '%#{params[:search]}%'").order('id').page(params[:page]).per(15)
In an offline discussion, it wasn't working. turns out he had BOTH will_paginate Gem and kaminari Gem for his pagination. He was crapping out when it came to .per(15). Deleting the will_paginate gem fixed it!
will_paginate isn't being actively upgraded, so if you have will_paginate and you are on Rails 3.X, get rid of will_paginate and use kaminari instead, it's a fairly painless swap out, just a bit of css work to format the pagination.
You need to combine those two calls into one, right now you are overriding the first setting of #groups with the second.
I'd add a scope to your group model
class Group
scope :search, lambda { |val| , find(:all, :conditions=>['description LIKE ?', "%#{val}%"]) }
end
Then you can do
#groups = Group.search(params[:search]).order("id").page(params[:page]).per(15)

Ruby/Rails Simple search form and white spaces

I've implemented a "simple search form" (railscasts #37) in my app, but I wonder how:
1.) I cannot display any results if the keywords field is empty, or if the index page is loaded (I've tried search != "". Maybe there is a better way)
2.) I can add a function which avoid multiple white spaces in the search. (if users wrote something like "benoit+++" or "++benoit" in the search box, it should display results)
I don't want to use thinking sphinx as I would deploy on heroku
Here is the code:
In my user model (user.rb)
def self.search(search)
if search and search != ""
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
end
In my 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 %>
<% if #users and not #users.empty? %>
<% #users.each do |user| %>
<p><%= link_to "#{user.name}", user %></p>
.
.
.
<% end %>
<% end %>
and in my controller ( users_controller.rb)
def index
#users = User.search(params[:search])
end
Thanks for any help or ressources!!
I would change the search method:
def self.search(search)
search.blank? ? [] : all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end
something.blank? returns true if something is nil or blank.
something.strip removes all the spaces at the beginning or end of a string. If name could be made of more than 1 word and you wanted to prevent from having more than one space between the words, you could do search.strip.squeeze(" ")
Oh, I don't think you need the if #users && !#users.empty? clause in your view now.

Resources