Search multiple fields with multiple values - ruby-on-rails

So what I have is a model Referent that has multiple attributes for example nom and prenom.
I was able to search each attribute in my model using one search value. But then I tried having one text_field for each attribute so for nom I would have one text_field and for prenom I would have another.
So it would search for all Referent who have that nom and that prenom but I'm not capable of seperating those two search. Right now it just take one of the value and search in both nom and prenom with the same value
View:
<h2>Search Referent</h2>
<%= form_tag(referents_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Nom" %>
<%= text_field_tag :search, params[:search], placeholder: "Prenom" %>
<%= submit_tag "Search", class: 'btn btn-info' %>
<% end %>
Controller:
def index
#referents = Referent.all
if params[:search]
#referents = Referent.search(params[:search]).order("created_at DESC")
else
#referents = Referent.all.order("created_at DESC")
end
end
Model:
def self.search(search)
where("nom || prenom ILIKE ?", "%#{search}%")
end
Right now it just seems to take the value of the second text_field and use that for the search. I'm using postgresql.
The full view:
<div class="container">
<h2>Search Referent</h2>
<%= form_tag(referents_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search_nom, params[:search], placeholder: "Nom" %>
<%= text_field_tag :search_prenom, params[:search], placeholder: "Prenom" %>
<%= submit_tag "Search", class: 'btn btn-info' %>
<% end %>
<h2>List de Referent</h2>
<table class="table table-hover">
<tr>
<th>Nom</th>
<th>Prenom</th>
<th>Titre</th>
<th>Departement</th>
<th>Cellulaire</th>
<th>Bureau</th>
<th>Fax</th>
<th>Courriel</th>
<th>Organisme Referent</th>
</tr>
<% #referents.each do |referent| %>
<tr>
<td><%= referent.nom %></td>
<td><%= referent.prenom %></td>
<td><%= referent.titre %></td>
<td><%= referent.departement %></td>
<td><%= referent.cellulaire %></td>
<td><%= referent.bureau %></td>
<td><%= referent.fax %></td>
<td><%= referent.courriel %></td>
<td><%= link_to referent.organismereferent.nom_organisation, organismereferent_path(referent.organismereferent_id) %></td>
</tr>
<% end %>
</table>
</div>
Error using Ramon answer

I would do it like this
<h2>Search Referent</h2>
<%= form_tag(referents_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search_nom, params[:search_nom], placeholder: "Nom" %>
<%= text_field_tag :search_prenom, params[:search_prenom], placeholder: "Prenom" %>
<%= submit_tag "Search", class: 'btn btn-info' %>
<% end %>
Controller
def index
#referents = Referent.all
search_nom = params[:search_nom]
search_prenom = params[:search_prenom]
#referents = Referent.search(search_nom, search_prenom).order("created_at DESC")
end
Model
def self.search(search_nom, search_prenom)
where("nom ILIKE ? or prenom ILIKE ?", "%#{search_nom}%", "%#{search_prenom}%")
end

Related

Rails search form with multiple params

I am working on a search form which should accept multiple params. But it currently accepts only one.
My Controller action:
def index
#halls = Hall.order(:name).page(params[:page]).per(9)
#city = City.all
#venue_type = VenueType.all
#event_type = EventType.all
if !params[:city].blank?
session[:city] = params[:city]
city = City.find_by(name: params[:city])
#halls = #halls.where(:city => city)
end
if !params[:venue_types].blank?
session[:venue_types] = params[:venue_types]
venue_types = VenueType.find_by(name: params[:venue_types])
#halls = #halls.where(:venue_types => venue_types)
end
if !params[:event_types].blank?
session[:event_types] = params[:event_types]
event_types = VenueType.find_by(name: params[:event_types])
#halls = #halls.where(:event_types => event_types)
end
end
My view:
<div class="search">
<%= form_tag(halls_path, :method => "get", class: "navbar-form", id: "search-form") do %>
<%= select_tag "city", options_from_collection_for_select(City.all, "name", "name") %>
<ul>
<% #venue_type.each do |venue| %>
<li>
<%= check_box_tag 'venue_type[]', venue.name -%>
<%= venue.name -%>
</li>
<% end %>
</ul>
<ul>
<% #event_type.each do |event| %>
<li>
<%= check_box_tag 'event_type[]', event.name -%>
<%= event.name -%>
</li>
<% end %>
</ul>
<button class="btn" type="submit">Search</button>
<% end %>
</div>
I bet the mistake is in the controller but as a newbie I can't find it.
Would be grateful for the answers.
Your view defined the check_box_tag with:
<%= check_box_tag 'venue_type[]', venue.name -%>
<%= venue.name -%>
<%= check_box_tag 'event_type[]', event.name -%>
<%= event.name -%>
As you see, your controller must get :value_type & :event_type from params instead of :value_types & :event_types. So you can change from either view or controller, it should work, but I recommend change from view like this:
<%= check_box_tag 'venue_types[]', venue.name -%>
<%= venue.name -%>
<%= check_box_tag 'event_types[]', event.name -%>
<%= event.name -%>

SyntaxError at /setups/new: syntax error, unexpected tIDENTIFIER, expecting keyword_end

my controller:
class SetupsController < ApplicationController
def new
#setup = Setup.new
#todays_rate = #setup.todays_rates.build
end
def create
#setup = Setup.new(params[:setup])
if #setup.save
redirect_to setup_path(#setup)
else
render 'new'
end
end
end
My view code: setup/new.html.erb
<%= form_for #setup, :html => {:multipart => true} do |f| %>
<% if #setup.errors.any? %>
<ul>
<% #setup.errors.full_messages.each do |error| %>
<li><strong><%= error %></strong></li>
<% end %>
</ul>
<% end %>
<h4><%= f.label :effective_from, class:'required' %>
<%= f.text_field :effective_from %></h4>
<h4><%= f.label :effective_to, class:'required' %>
<%= f.text_field :effective_to %></h4>
<%= f.fields_for(:todays_rate) do |i| %> ##**combining two model with one view**
<h1>Interest Rate</h1>
<table cellpadding = "5px" cellspacing = "5px" width = "100%" class="table condensed-table"><tr>
<h4><th>Days From</th>
<th>Days To</th>
<th>Rate</th>
<th>Senior increment</th>
<th>Super Senior increment</th>
<th>Widow increment</th></h4>
</tr>
<h4><td><%= i.text_field :days_from, :class => 'input-mini' %></td></h4>
<h4> <td><%= i.text_field :days_to, :class => 'input-mini' %></td></h4>
<h4><td><%= i.text_field :rate, :class => 'input-mini' %></td></h4>
<h4> <td><%= i.text_field :senior_increment, :class => 'input-mini' %></td></h4>
<h4> <td><%= i.text_field :super_senior_increment,class:"input-mini" %></td></h4>
<h4><td><%= i.text_field :widow_incrtement,class: "input-mini" %></td></h4>
</table>
<% end %>
<fieldset class="form-actions"> <%= f.submit "Create Customer", class: "btn btn-primary" %></field>
setup.rb mmodel:
class Setup < ActiveRecord::Base
has_many :todays_rates
accepts_nested_attributes_for :todays_rates
attr_accessible :effective_from, :effective_to, :todays_rate
end
i'm combining two model in one view but i'm getting the above error. i don't know where i missed the keyword_end.can any one help me
I think your problem is that you haven't closed the form, ie you need a <% end %> at the end of your template.
The error sort of tells you that, though the tIDENTIFIER stuff can throw one off the scent a bit.

An Error when showing group_path(#group)

Now, I tried to set up the route with group_path(#group) but got an error message like,
ActiveRecord::RecordNotFound at /groups/%23%3CActiveRecord::Relation:0x007fd6cf362538%3E
Couldn't find Group with id=#<ActiveRecord::Relation:0x00fds6cf362538>
Here is my code. I would like to set up a link to groups/show/:id. Why did this error occur? Could you give me how to solve this?
☆index.html.erb
<% if #items.present? %>
<% #items.each do |i| %>
<% i_attr = i.get_element('ItemAttributes') %>
<tr>
<td> <%= link_to image_tag(i.get('SmallImage/URL'), {:style => 'border: none;'}), i_attr.get('DetailPageURL') %></td>
<td> <%= link_to i_attr.get('Title'), i_attr.get('DetailPageURL') %></td>
<td> <%= i_attr.get('Author') %></td>
<td> <%= i_attr.get('PublicationDate')%></td>
<td> <%= i_attr.get('Publisher') %></td>
<td> <%= i_attr.get('NumberOfPages')%></td>
<td>
<% if #existing_groups_isbns.include? i_attr.get('ISBN') %>
<% #existing_groups_isbns.each do |isbn| %>
<% if isbn == i_attr.get('ISBN') %>
<% #group = Group.where(:isbn =>isbn) %>
<%= link_to '既存ページへ' , group_path(#group) %>
<% end %>
<% end %>
<% else %><!-- if includes?==-->
<%= link_to '新規作成', {:controller => 'groups', :action => 'new', :name => i.get('ItemAttributes/Title'),:author => i.get('ItemAttributes/Author'), :publish => i.get('ItemAttributes/Publisher'), :published => i.get('ItemAttributes/PublicationDate'), :isbn => i.get('ItemAttributes/ISBN'), :page => i.get('ItemAttributes/NumberOfPages'), :imageurl=>i.get('MediumImage/URL')} ,class: "btn btn-midium btn-primary"%>
<% end %><!--if includes?-->
</td>
</tr>
<% end %><!-- #items.each do-->
<% else %><!--if #items.present?-->
見つかりませんでした。
<% end %><!-- if #items.present?-->
☆index_controller
def index
#keyword = params[:keyword]
if #keyword.present?
Amazon::Ecs.debug = true
res = Amazon::Ecs.item_search(params[:keyword],
:search_index => 'All', :response_group => 'Medium')
#items = res.items
search_isbns = #items.map{ |isbns| isbns.get('ItemAttributes/ISBN')}
search_asins = #items.map{ |asins| asins.get('ItemAttributes/ASIN')}
#existing_groups_isbns = Group.select(:isbn).where(:isbn => search_isbns).map(&:isbn)
#existing_groups_ids = Group.where(:isbn => search_isbns).map{|g| g.id}
end
Replace
<% #group = Group.where(:isbn =>isbn) %>
with
<% #group = Group.where(:isbn =>isbn).first %>
Because you need an object where you had an ActiveRecord relation

show child checkboxes under parent checkboxes in view page rails

I am showing check boxes in view page and data will come from the database. Here is my code and the problem is that while looping if the same parent name came it shows same parent checkboxes two times.
<% #permission.each do |f| %>
<% if #controller_code != f.controller_code %>
<% #controller_code = f.controller_code %>
<%= check_box_tag "cntrl_#{f.controller_code}", f.controller_code, false, :class => "Par_#{f.controller_code}", :id => "Par_#{f.controller_code}" %> <%= f.controller_name %>
<br/>
<% #permission.each do |f| %>
<% if #controller_code == f.controller_code %>
<%= check_box_tag "action_#{f.controller_code}_#{f.action_code}",f.action_code, false, :class => "Child_#{f.controller_code}", :id => "Child_#{f.controller_code}_#{f.action_code}" %> <%= f.action_name %>
<br/>
<% end %>
<% end %>
<% end %>
I have also tried this way but its not working properly..
<% #permission.each do |f| %>
<% if #controller_code != f.controller_code %>
<% #controller_code = f.controller_code %>
<%= check_box_tag "cntrl_#{f.controller_code}", f.controller_code, false, :class => "Par_#{f.controller_code}", :id => "Par_#{f.controller_code}" %> <%= f.controller_name %>
<br/>
<% end %>
<%= check_box_tag "action_#{f.controller_code}_#{f.action_code}",f.action_code, false, :class => "Child_#{f.controller_code}", :id => "Child_#{f.controller_code}_#{f.action_code}" %> <%= f.action_name %>
<br/>
<% end %>
I dont know that i m giving exact answer for your question, i think this can help you,
<% #permission.each do |f| %>
<% if #controller_code != f.controller_code %>
<% #controller_code = f.controller_code %>
<%= check_box_tag "cntrl_#{f.controller_code}", f.controller_code, false, :class => "Par_#{f.controller_code}", :id => "Par_#{f.controller_code}" %> <%= f.controller_name %>
<% else %>
<%= check_box_tag "action_#{f.controller_code}_#{f.action_code}",f.action_code, false, :class => "Child_#{f.controller_code}", :id => "Child_#{f.controller_code}_#{f.action_code}" %>
<%= f.action_name %>
<% end %>
<% end %>
I found the solution of my question here it is in controller do following
#permission=Permission.all.where(active: 1)
if #permission.blank? == false
#permissions = Permission.all.where(active: 1).order_by(:controller_code => "asc")
else
#permissions = ""
end
And in view page do following
<% #permissions.each do |f| %>
<% if #controller_code != f.controller_code %>
<% #controller_code = f.controller_code %>
<%= check_box_tag "cntrl_#{f.controller_code}", f.controller_code, false, :class => "Par_#{f.controller_code}", :id => "Par_#{f.controller_code}" %> <%= f.controller_name %>
<br/>
<% #permissions.each do |f| %>
<% if #controller_code == f.controller_code %>
<%= check_box_tag "action_#{f.controller_code}_#{f.action_code}",f.action_code, false, :class => "Child_#{f.controller_code}", :id => "Child_#{f.controller_code}_#{f.action_code}" %> <%= f.action_name %>
<br/>
<% end %>
<% end %>
<% end %>
<% end %>

Ruby on Rails: Show results on page, after search

I am trying to hide my search results until after the search has happened. At the moment when I click from the home page to the search page, the page shows the search boxes, but also shows all of the database in a table. I am wanting to just show the search options, and search button, then depending on the search, show the right table.
Here is my search view:
<h1>Search</h1>
<%= form_tag search_path, method: :get do %>
Client :
<%= select(#projects, :client, Project.all.map {|p| [p.client]}.uniq, :prompt => "-Any-", :selected => params[:client]) %></br>
Industry :
<%= select(#projects, :industry, Project.all.map {|p| [p.industry]}.uniq, :prompt => "-Any-", :selected => params[:industry]) %></br>
Role :
<%= select(#projects, :role, Project.all.map {|p| [p.role]}.uniq, :prompt => "-Any-", :selected => params[:role]) %></br>
Technologies :
<%= select(#projects, :tech, Project.all.map {|p| [p.tech]}.uniq, :prompt => "-Any-", :selected => params[:tech]) %></br>
Business Division :
<%= select(#projects, :business_div, Project.all.map {|p| [p.business_div]}.uniq, :prompt => "-Any-", :selected => params[:business_div]) %></br>
Project Owner :
<%= select(#projects, :project_owner, Project.all.map {|p| [p.project_owner]}.uniq, :prompt => "-Any-", :selected => params[:project_owner]) %></br>
Exception PM
<%= select(#projects, :exception_pm, Project.all.map {|p| [p.exception_pm]}.uniq, :prompt => "-Any-", :selected => params[:exception_pm]) %></br>
Start Date :
<%= text_field_tag("start_date") %></br>
End Date :
<%= text_field_tag("end_date") %></br>
Status :
<%= select(#projects, :status, Project.all.map {|p| [p.status]}.uniq, :prompt => "-Any-", :selected => params[:status]) %></br>
Keywords :
<%= text_field_tag :keywords, params[:keywords] %></br>
<%= submit_tag "Search", name: nil %>
<% end %>
<% if #search %>
<h3><%=#project_search.total_entries%> results</h3>
<% end %>
<% if #search %>
<table class = "pretty">
<table border="1">
<tr>
<th><%= sortable "project_name", "Project name" %> </th>
<th><%= sortable "client", "Client" %></th>
<th>Exception pm</th>
<th>Project owner</th>
<th>Tech</th>
<th>Role</th>
<th>Industry</th>
<th>Financials</th>
<th>Business div</th>
<th>Status</th>
<th>Start date</th>
<th>End date</th>
<% if false %>
<th>Entry date</th>
<th>Edited date</th>
<th>Summary</th>
<th>Lessons learned</tStackh>
<th>Customer benifits</th>
<th>Keywords</th>
<!th></th>
<!th></th>
<!th></th>
<% end %>
</tr>
<%# end %>
<% #project_search.each do |t| %>
<tr>
<td><%= t.project_name %></td>
<td><%= t.client %></td>
<td><%= t.exception_pm %></td>
<td><%= t.project_owner %></td>
<td><%= t.tech %></td>
<td><%= t.role %></td>
<td><%= t.industry %></td>
<td><%= t.financials %></td>
<td><%= t.business_div %></td>
<td><%= t.status %></td>
<td><%= l t.start_date %></td>
<td><%= l t.end_date %></td>
<% if false %>
<td><%= t.entry_date %></td>
<td><%= t.edited_date %></td>
<td><%= t.summary %></td>
<td><%= t.lessons_learned %></td>
<td><%= t.customer_benifits %></td>
<td><%= t.keywords %></td>
<% end %>
<!td><%#= link_to 'Show', project %></td>
<!td><%#= link_to 'Edit', edit_project_path(project) %></td>
<!td><%#= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
Results per page: <%= select_tag :per_page, options_for_select([10,20,50], params[:per_page].to_i), :onchange => "if(this.value){window.location='?per_page='+this.value;}" %>
<br />
<%= hidden_field_tag :direction, params[:direction] %>
<%= hidden_field_tag :sort, params[:sort] %>
<%= hidden_field_tag :per_page, params[:per_page] %>
<%= hidden_field_tag :page, params[:page] %>
<%= will_paginate (#project_search) %>
<%= button_to "Search Again?", search_path, :method => "get" %>
<%# end %>
<%= button_to "Home", projects_path, :method => "get" %>
Here is the search action:
def search
#search = params[:client], params[:industry], params[:role], params[:tech], params[:business_div], params[:project_owner], params[:exception_pm], params[:status], params[:start_date], params[:end_date], params[:keywords]
#project_search = Project.search(#search)
#project = Project.new(params[:project])
respond_to do |format|
format.html # search.html.erb
format.json { render :json => #project }
end
end
and here is my model.
class Project < ActiveRecord::Base
attr_accessible :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
validates_presence_of :business_div, :client, :customer_benifits, :end_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
def self.search(search_client, search_industry, search_role, search_tech, search_business_div, search_project_owner, search_exception_pm, search_status, search_start_date, search_end_date, search_keywords)
return scoped unless search_client.present? || search_industry.present? || search_role.present? || search_tech.present? || search_business_div.present? || search_project_owner.present? || search_exception_pm.present? || search_status.present? || search_start_date.present? || search_end_date.present? || search_keywords.present?
if search_start_date != ""
search_start_date = Date.parse(search_start_date).strftime("%Y-%m-%d")
end
if search_end_date != ""
search_end_date = Date.parse(search_end_date).strftime("%Y-%m-%d")
end
where(['client LIKE ? AND industry LIKE ? AND role LIKE ? AND tech LIKE ? AND business_div LIKE ? AND project_owner LIKE ? AND exception_pm LIKE ? AND status LIKE ? AND start_date LIKE ? AND end_date LIKE ? AND keywords LIKE ?', "%#{search_client}%", "%#{search_industry}%" , "%#{search_role}%" , "%#{search_tech}%" , "%#{search_business_div}%" , "%#{search_project_owner}%" , "%#{search_exception_pm}%" , "%#{search_status}%", "%#{search_start_date}%", "%#{search_end_date}%","%#{search_keywords}%"])
end
def self.paginated_for_index(projects_per_page, current_page)
paginate(:per_page => projects_per_page, :page => current_page)
end
end
Hopefully you can see what I have tried to do. I am getting the error wrong number of arguments (1 for 11) as I haven't split the params. But when I use *#search I get loads of errors.
My original code in the controller looked like this before I went about trying to hide the table:
#project_search = Project.search(params[:client], params[:industry], params[:role], params[:tech], params[:business_div], params[:project_owner], params[:exception_pm], params[:status], params[:start_date], params[:end_date], params[:keywords]).order(sort_column + ' ' + sort_direction).paginated_for_index(per_page, page)
You need to splat the #search params when passing it to .search to tell Ruby to expand your array of arguments to separate arguments to be passed to Project.search
#project_search = Project.search(*#search)
Information on using splat
Edit (to answer your follow-up question)
Testing with
<% if #search %>
isn't enough because it will always have a value that evaluates to true, even if its just [] or ["", "", "", "", "", "", "", "", "", "", ""]. One way to check this properly would be to create a new boolean instance variable that is true if all fields are blank in the search filters.
# put this after you set #search in your action
#search_performed = !#search.reject! { |c| c.blank? }.empty?
and now test #search_performed in your view with
<% if #search_performed %>
you are storing array in #search and u have to use * operator
#project_search = Project.search(*#search)

Resources