At the moment I am trying to create a search within a project to bring up users depending on their region. From what I understand, I basically need to place the search params in the controller, the self.search method in the model, and then the form in the view.
In another project, I have a search but it shows all the options above and use the search to filter out those which do not match. For this situation, I do not want to list any users in the beginning. I want to use the search bar and bring up any users that match within that view page. Additionally I use Devise for users if that does make a difference. Here are my three regions of code:
Model (user.rb):
def self.search(search)
where("state ILIKE ?", "%#{search}%")
end
Controller (welcome_controller.rb):
def index
#users = User.all.order("created_at DESC")
#newusers = User.all.order("created_at DESC").limit(5)
#differentlocations = User.all.group_by(&:state).count
render :layout => 'with_newest_members'
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
end
View (find.html.erb):
<%= form_tag(find_path, :method => "get") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Posts" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
Please let me know if you have any knowledge for me to help =) Any additional explanation would be greatly appreciated to help me understand, thank you!
Edit: I know I need to enter the results portion but I am confused about how/where to put it.
Joe
ANSWER:
The issue was in my controller because I had a render command prior to the search code. The controller should be:
def index
#users = User.all.order("created_at DESC")
#newusers = User.all.order("created_at DESC").limit(5)
#differentlocations = User.all.group_by(&:state).count
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
render :layout => 'with_newest_members'
end
Fantastic =)
Two small things that might help:
1) In your Search model, I believe you have a typo in your search method. It should read as follows:
def self.search(search)
where("state LIKE ?", "%#{search}%")
end
You might also want to consider a more description name for your argument, such as state.
2) In your form, you don't need to explicitly write params[:search] anywhere. The params hash will be generated for you in the controller, with the name of the text_field as the key and the value inputted by the user as the value (see Ruby docs here). In this case, use :search as the name of the text_field_tag name.
<%= form_tag(find_path, :method => "get") do %>
<%= text_field_tag :search, placeholder: "Search Posts" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
More on FormHelpers here.
Related
I am creating a rails app where I have implemented the following search function.
application.html.erb
<div class="searchbar">
<%= form_tag(articles_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: " Search", :class => "search_form" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</div>
article.rb
def self.search(search)
where("title LIKE ? OR creator LIKE ? OR description LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
end
articles_controller.rb
def index
#articles = Article.all
if params[:search]
#articles = Article.search(params[:search]).order("created_at DESC")
else
#articles = Article.all.order("created_at DESC")
end
end
This allows me to search for all primary resources but does not include nested resources in the search results. Is there a way to include these resources within the same function?
You'd need to do some joins, and define a syntax for passing the relevant join info into your search method.
This can get complicated pretty quick, and I'd highly suggest you don't reinvent the wheel and use an existing solution such as ransack. This will let you do things like
Article.ransack(title_cont: "code", author_name_cont: "bob").result
where, in this example, Author is its own model, associated with Article, and containing the field name.
It also plays very nice with views and forms, so you can very easily implement search forms without having the manually key everything up to the right association and field.
(Personally I'm not in love with their concatenation syntax but it gets the job done.)
How can I call a method with a hyperlink on my index.html.erb?
I currently have a search field that allows the user to type in a keyword. This will search attributes in a model and display any that are found.
For example, I have records_controller.rb with this in it:
def index
#records = Record.search(params[:search])
end
app/models/record.rb has:
# Added for the search
def self.search(search)
where("title LIKE ? OR keyword LIKE ? OR description LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
end
'title, 'keyword', and 'decscription' are attributes in the model.
app/views/records/index.html.erb contains a search form:
<%= form_tag(records_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: " Search" %>
<%= submit_tag "Find" %>
<% end %>
On this same index.html.erb page, how can I add a hyperlink that displays all data from a model that contains a title I specify?
Such as displaying all rows that have the title "truck".
If the user clicks the hyperlink, it will display data
where('title LIKE "truck"', "%#{search}%")
I'm assuming I'll also need to put a new method in the record model such as:
# I'll have to play with this because I know it is wrong
# Added for the search
def self.searchtruck(search)
where('title LIKE "truck"', "%#{search}%")
end
This does what you're asking, creates a link with the param[:search] = 'truck'
<%= link_to 'Search for truck', records_path(search: 'truck') %>
I am trying to implement a simple search feature on my site. Currently, when I use my search bar it will work, but if the result is not found then it will pull up a blank page. I am using PostgreSQL
this is my form in recipes/index.html.erb
<%= form_with(url: recipes_path, method: :get, local: true) do |form| %>
<%= form.text_field(:term, {class: 'form-control', type:'search',
arialabel:'search', placeholder: 'search by recipe name'})%>
<%= form.submit 'Search', class: 'btn btn-dark bg-dark' %>
<% end %>
this is my controller index action in the recipes_controller.rb
def index
#recipes = if params[:term]
Recipe.where('name LIKE ?', "%#{params[:term]}")
else
Recipe.all
end
#categories = Category.all
end
I would like to redirect the user back to to the index view and display a message that says something like "the recipe was not found, please search for a different recipe."
In your Index file,
<%= form_tag('/recepies/', :method => :get, :role => 'form') do %>
<%= text_field_tag :term, :class => "form-control", :placeholder => "Search"%>
<button class='glyphicon glyphicon-search' type="search">
</button>
<% end %>
In your controller,
def index
if params[:term].present?
#recipes = Recepie.all
#recipes = #recipes.find_term(params[:term].strip) if params[:term].present?
if #recipes.blank? {
flash[:notice] = 'the recipe was not found, please search for a different recipe.'
}
end
else
#recipes = Recepie.all
end
end
In your Model,
def self.find_term(term)
recipes = all
recipes = posts.where("recipes.term= ?", term)
end
when I use my search bar it will work, but if the result is not found
then it will pull up a blank page.
So your search works but it has no results.
I would like to redirect the user back to to the index view and
display a message that says something like "the recipe was not found,
please search for a different recipe."
You could do something like #recipes.any? to check if you got some results. If you check in the controller you can redirect and use the flash for messages, or you can simply do it in the view and render the message.
PS: Not that you ask, but I really like to use ransack for complex search functionality.
I want to be able to search and update the index.
this is my controller method:
def index
if params[:search]
#ofertas = Oferta.search(params[:search]).paginate(page: params[:ofertas_page], :per_page => 5)
else
#ofertas = Oferta.all.paginate(page: params[:ofertas_page], :per_page => 5)
end
end
My search method in the model
def self.search(search)
where("titulo like ?","%w{search}%")
end
and this is the search form
<%= form_tag ofertas_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search], placeholder: "Procurar Entidades" %>
<%= submit_tag "Procurar", :name => nil %>
</p>
<% end %>
I've seen this setup in a number of search tutorials but no matter what I type nothing appears. Does someone know what I'm doing wrong?
It looks like you were trying to interpolate the search variable into the string, but didn't quite get the right symbol. How about this:
"%#{search}%"
Note the # instead of the w.
where("titulo like ?","%w{search}%")
should be:
where("titulo like ?", "%#{search}%")
#{xxx} is for string interpolation - it allows you to inject ruby (including variables) into a string.
"%xxxx%" is telling SQL that the search string can appear anywhere in the titulo column. '%' is a wildcard in SQL.
%w{xxx yyy zzz} is shorthand for ["xxx", "yyy", "zzz"] - an array in Ruby, which wouldn't mean much to the SQL as a string by itself.
I have a simple search working in my rails app, but it only searches a single column of my table. I'm trying to add a simple dropdown menu with options like "last_name" and "city" so the user can select the column to search.
In my view I have:
<%= form_tag teachers_path, :method => 'get', :id => "teachers_search" do %>
<%= hidden_field_tag :direction, params[:direction]%>
<%= hidden_field_tag :sort, params[:sort]%>
<p>
<%= text_field_tag :search, params[:search], placeholder: 'First Name' %>
<%= submit_tag "Search", :first_name => nil %>
</p>
<% end %>
and in my model:
def self.search(search)
if search
where('first_name LIKE ?', "%#{search}%")
else
scoped
end
end
Any help greatly appreciated.
You can add a select_tag for your drop down menu
<%= select_tag "search_from", "<option>first_name</option><option>last_name</option><option>city_name</option>".html_safe%>
In your controller you can pass the value in params[:search_from] to your search method. and modify it to include the column name
def self.search(search, column_name)
if search
where('? LIKE ?', column_name, "%#{search}%")
else
scoped
end
end
I've written it in a crude way but i hope it gets the message along.
extending #sohaibs's answer dropdown is a good idea if you are only allowing user to filter result with some some fixed attributes
views
<%= select_tag "search_by", options_for_select(['first_name','last_name','city'].map{|o| [o.humanize,o] }) %>
<%= f.text_field 'search' %>
controller
def search
User.search params[:teacher][:search_by],params[:teacher][:search]
end
and model
def self.search(search_by,search_value)
where('? LIKE ?', search_by, search_value)
end
Awesome Rails :)
Have you tried:
def self.search(column, search)
# some logic
where('? LIKE ?', column, "%#{search}%")
# some logic
end