I am trying to create a search page that searches through the model courses. Courses has a "name" column that lists the names of courses. I created a search controller and this is what I have on my search controller:
class SearchController < ApplicationController
def search
if params[:search].blank?
redirect_to(root_path, alert: "Empty field!") and return
else
#parameter = params[:search].downcase
#results = Courses.all.where("lower(name) LIKE :search", search: #parameter)
end
end
def show
render 'search'
end
end
I have under views/search a search.html.erb page. On this page I have
<%= form_tag(search_path, :method => "get",
class: 'navbar-form navbar-left') do %>
<div class="input-group">
<%= search_field_tag :search, params[:search], placeholder: "Search", class: "form-control" %>
<div class="input-group-btn">
<%= button_tag "", :class => 'btn btn-info glyphicon glyphicon-search',:name => nil%>
</div>
</div>
<% end %>
<h3>Search Result</h3>
<% #results.each do |result| %>
<%= result.name %><br>
<% end %>
However, I am getting the following error when I run my rails server and click on search and I am not sure why #results is null. Thanks for the help!
11: <h3>Search Result</h3>
12:
13: <% #results.each do |result| %>
14: <%= result.name %><br>
15: <% end %>
When the form provided in app/views/search/search.html.erb is submitted, the request is sent to show action by default. But the show action just renders the search view, no #results is assigned and the error occurs.
The search action seems unnecessary and you should use the show action instead. For example, rename app/views/search/search.html.erb to app/views/search/show.html.erb and move the search code to show action as below:
app/controllers/search_controller.rb
class SearchController < ApplicationController
def show
if params[:search].blank?
redirect_to(root_path, alert: "Empty field!")
else
#parameter = params[:search].downcase
#results = Courses.all.where("lower(name) LIKE :search", search: #parameter)
end
end
end
Related
Sort of new in rails so i might be doing things the wrong way
show.html.erb:
<% #feature.each do |p| %>
<br>
<h1><%= p.name %></h1>
<%= p.unit_price %>
<%= render partial: "shared/featureuse_form", locals: {feat_use: #feat_use , feature: p} %>
<%= button_to'Change' , feature_use_path(1) , :class => 'btn btn-primary' ,method: :delete %>
<% end %>
Right here in feature_use_path how do i get an id to pass it in order to make a delete button as i havent even created the model yet or its saved in its own controller should
_featureuse_form.html.erb:
<%= form_with model: feat_use do |f| %>
<%= f.number_field :total_units ,value: feature.max_unit_limit %>
<%= f.hidden_field :feature_id, value: feature.id %>
<%= f.hidden_field :usage_id, value: current_user.usage.id %>
<%= f.submit "confirm", id: "button"%>
<% end %>
Plans Controller
class PlansController < ApplicationController
before_action :authenticate_user!
def index
#plan = Plan.all
end
def show
#plan = Plan.find(params[:id])
#feature = #plan.features
#feat_use = FeatureUse.new
end
end
class FeatureUsesController < ApplicationController
def create
feature_use = FeatureUse.new(feature_use_params)
feature_use.total_units = params[:feature_use][:total_units]
feature_use.feature_id = params[:feature_use][:feature_id]
user = current_user.usage
feature_use.usage_id = user.id
feature_use.save
end
end
You're right that you can't create a button (method: :delete or otherwise) that relies on a record that doesn't yet exist.
Usually, a button like this would only be relevant to existing records anyway.
So, it's common to see an if statement like this:
<% if #feature_use.persisted? %>
<%= button_to 'Change' , feature_use_path(#feature_use.id) , :class => 'btn btn-primary', method: :delete %>
<% end %>
.persisted? returns false if the record is new and un-saved.
My question
With Ransack, when submit is clicked, is there a way to call a method before displaying the results on another page.
Summary
I have a page called manualPull that contains a single search_field:
<%= search_form_for #q do |f| %>
<div class="field">
<%= f.label :Username_cont, "Lookup" %>
<%= f.search_field :Username_cont %>
</div>
<div class="actions"><%= f.submit "Pull & Search"%></div>
<% end %>
Basically what I want to happen is when a user clicks on the submit button, we will send a call to the controller of another page (sessions_controller#manuallookupsession) to pull data from our database then show the results on that other page.
What I tried
I tried adding url: 'sessions_controller#manuallookupsession' to search_form_for :
<%= search_form_for #q do |f|, url: 'sessions_controller#search' %>
<div class="field">
<%= f.label :Username_cont, "Lookup" %>
<%= f.search_field :Username_cont %>
</div>
<div class="actions"><%= f.submit "Pull & Search"%></div>
<% end %>
I also added the following line to the sessions_controller before_action :index, only: [:search]
That almost worked in the sense that it would show the search results in the new page but it would not run the manuallookupsession method in the sessions_controller. The other weird behavior is that the manuallookupsession method would run every time I refresh the manualPull page but not when I clicked submit.
Update1:
session_controller
Here is the code for my session_controller:
class PppoeSessionsController < ApplicationController
before_action :index, only: [:search]
def index
#q = Session.ransack(params[:q])
#session = #q.result.order(:username).page params[:page]
#sessions_to_export = #q.result.order(:username).all
respond_to do |format|
format.html
format.csv { render text: #sessions_to_export.to_csv }
format.xlsx
end
end
end
def search
puts("TEST")
#username = params[ 'username' ]
#sessionsearch = Session.new
#sessiondetails = Session.new
if #username
#sessiondetails = #sessionsearch.pull_user(#username)
respond_with(#pppoe_session)
end
end
According your given informations, your before_action syntax it's a bit weird, can you replace it by this one:
before_action :search, only: [:index], if: -> { params[:username] }
In this way you should also remove your if statement inside your search method within the session_controller.
Here is what worked for me finally:
In my search_form_for I added a hidden field called search as follows:
<%= search_form_for #q, url: 'sessions_controller' do |f| %>
<div class="field">
<%= f.label :username_eq, "Lookup" %>
<%= f.search_field :username_eq %>
<%= hidden_field_tag "search", true %>
</div>
<div class="actions"><%= f.submit "Refresh & Search" %></div>
<% end %>
And in my sessions_controller I added the following check to my index class:
if params[:search] == "true" && params[:commit] == "Refresh & Search"
search #This is a call to a method
end
Furthermore in my search class I was able to retrieve the entered username from the URL (since it was a get request and not a post request) with the following code (you need to require 'cgi' at the start of the class):
url = request.original_fullpath.split("/").last
parameter_hash = CGI.parse(URI.parse(url).query)
#username = parameter_hash["q[username_eq]"][0].to_s
Thanks to #morissetcl for leading me to the correct answer in the comments of your last answer.
I wish there was a way to give you credits for it.
This is the form that I made from Clients_indexI am using Elastic Search to find a client's name. I created a search for but as soon as you click search it takes me to a second page.
It takes me here
Here is my view for Clients/_index.html.erb
<label for="existing-ads-client-name" class="big">CLIENT INFORMATION</label><br>
<div class="existing-ads-client-name">
<%=form_tag clients_path,class: 'search-client', method: :get do |f| %>
<div id="client-name">
<%=text_field_tag :name, params[:name] %>
</div>
<%=button_tag "Search", class: 'btn btn-default', name: nil %>
<% end %>
</div>
I am rendering it from AdGroups/index.html.haml
<div class="module existing-ads">
<div class="first-column">
<div class="field-content">
=render 'clients/index'
And here is my Clients controller
class ClientsController < ApplicationController
def index
#clients = Client.search((params[:name].present? ? params[:name]: '*')).records
render :partial => 'clients/index', locals: {clients: #clients}
end
end
Any idea why?
I have a similar question to this but still can't figure it out.
I am creating a rails app linked to a Neo4j database and have a number of models I want to search across with one search form. I am using elastic search.
My current code for searching within one model (works fine):
#/app/views/symptoms/index.html
<%=form_tag symptoms_path, class: "form-inline", method: :get do %>
<div class="form-group">
<%= text_field_tag :query, params[:query], class: "form-control" %>
<%= submit_tag "Search", class: "btn btn-primary" %>
<% if params[:query].present? %>
<%= link_to "clear" %>
<% end %>
</div>
<% end %>
#/app/controllers/symptoms_controller.rb
def index
if params[:query].present?
#symptoms = Symptom.search(params[:query], show: params[:show])
else
#symptoms = Symptom.all
end
end
Currently this will only search within the symptoms model. I want to to create a 'global search' field that will search within the symptoms_path, allergies_path, and drugs_path.
Potential 'Global Search' code:
#/app/views/global_search/index.html
<%=form_tag [symptoms_path, allergies_path, drugs_path], class: "form-inline", method: :get do %>
<div class="form-group">
<%= text_field_tag :query, params[:query], class: "form-control" %>
<%= submit_tag "Search", class: "btn btn-primary" %>
<% if params[:query].present? %>
<%= link_to "clear" %>
<% end %>
</div>
<% end %>
#/app/controllers/symptoms_controller.rb
def index
if params[:query].present?
#allergies = Allergy.search(params[:query], show: params[:show])
#drugs = Drug.search(params[:query])
#symptoms = Symptom.search(params[:query])
else
#allergies = Allergy.all
#drugs = Drug.all
#symptoms = Symptom.all
end
end
Any ideas for how I could implement this? Thanks in advance!
I'd probably suggest that you create something like a "search_controller" (rails generate controller search should help you do that). In there you can have an index action (or whatever you want to call your action) and then you just set up a route to point a URL to it such as this:
# config/routes.rb
# Link the URL to the search controller's `index` action
post '/search/:query' => 'search#index'
# app/controllers/search_controller.rb
def index
if params[:query].present?
#allergies = Allergy.search(params[:query], show: params[:show])
#drugs = Drug.search(params[:query])
#symptoms = Symptom.search(params[:query])
else
#allergies = Allergy.all
#drugs = Drug.all
#symptoms = Symptom.all
end
end
Sorry if I'm misunderstanding, I'm not sure how much you've worked with Rails before
I have two different controllers (scholarships_controller, scholarships_browse_controller) that look at the scholarship model. I want my Ransack search function to show the search results on the current page. So, for example, if I am on /scholarships_browse and I use the search functionality, I want it to use the scholarships_browse_controller and show the results on /scholarships_browse.
Currently, if I search on /scholarships_browse it uses the scholarships_controller and redirects to /scholarships to show the results (instead of /scholarships_browse).
Code for ScholarshipsBrowseController and ScholarshipsController
def index
#search = Scholarship.search(params[:q])
#scholarships = #search.result.page(params[:page]).per(3) #allows 3 scholarships on a page at a time
#search.build_condition
respond_to do |format|
format.html # index.html.erb
format.json { render json: #scholarships }
end
end
Code for scholarships browse index.html.erb:
<%= search_form_for #search do |f| %>
<%= f.condition_fields do |c| %>
<div class="field">
<%= c.attribute_fields do |a| %>
<%= a.attribute_select %>
<% end %>
<%= c.predicate_select compounds: false, only: [:cont, :eq, :gt, :lt] %>
<%= c.value_fields do |v| %>
<%= v.text_field :value %>
<% end %>
</div>
<% end %>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
So, I guess specifically I'm asking how do I make sure I am using the ScholarshipsBrowseController index instead of ScholarshipsController index when I am on /scholarships_browse ?
On your view:
<%= search_form_for #search, url: RAILS_ROUTEHERE do |f| %>
...
<%- end %>
search_form_for its an extension for form_for, so you can use the :url parameter to tell the form what should be the action of it (you can check the page source code when you render it on browser, you can check the tag <form action=""> to make sure it points to the right route.