Rails, using scopes to filter table - ruby-on-rails

i am fairly new to rails and i have to update an existing project. I have an existing database, beforehand it was just one User group, now there should be multiple. Now i want to use the old view, but filter with the help of a dropdown menu, but for some reason i can't work out what i am doing wrong.
Here are the code snippets i changed, since it was working beforehand, i assume my mistake must be somewhere within these lines.
event.rb
scope :men, lambda { { :conditions => ["team_id == ?", 1] } }
scope :women, lambda { { :conditions => ["team_id == ?", 2] } }
scope :juniors, lambda { { :conditions => ["team_id == ?", 3] } }
events_controller.rb
def index
# #events = Event.where("startdate >= ?", Date.today).order("startdate, starttime")
# #events = Event.order("startdate, starttime")
if params[:search]
#events = Event.search(params[:search])
else
if params[:filter].nil?
#events = Event.all
else
if params[:filter] == "Alle" then #events = Event.all end
if params[:filter] == "Men" then #events = Event.men end
if params[:filter] == "Women" then #events = Event.women end
if params[:filter] == "Juniors" then #events = Event.juniors end
end
end
end
and the index.html.erb
<div class="left">
<%= form_tag events_path, :method => 'get' do %>
<%= select_tag "filter", options_for_select([ "Alle", "Men", "Women", "Juniors" ], params[:filter]), {:onchange => 'this.form.submit()'} %>
<% end %>
probably it is a simple mistake. My guess is, that in the index.html.erb i am doing something wrong.
as a follow up, i want to filter just the events which are upcoming, for that i can use the commented part in the controller. can i just add that to the assignmnet in the style of:
#events = Event.men.where("startdate >= ?", Date.today).order("startdate, starttime")
thanks for the help
Lenny

You should change your scopes to new syntax:
scope :men, -> { where(team_id: 1) }
scope :women, -> { where(team_id: 2) }
scope :juniors, -> { where(team_id: 3) }
Your controller logic is a little buggy and twisted (checking 5 times filter isnt best way, why checking e.g. if filter is "Men" if you already matched it with "Alle" ?). Here is some help:
#events = if params[:search].present?
Event.search(params[:search].to_s)
else
case params[:filter]
when "Men"
Event.men
when "Women"
Event.women
when "Juniors"
Event.juniors
else
Event.all
end
end
Speaking about view, you shouldnt use inline js, just because its XXI century, and such "quick solutions" are harder to maintain later, so:
<div class="left">
<%= form_tag events_path, :method => 'get' do %>
<%= select_tag "filter", options_for_select([ "Alle", "Men", "Women", "Juniors" ], params[:filter]), class: 'my_filter' %>
<% end %>
and then add to your events.coffee:
$('select.my_filter').on 'change', ->
$(this).parents('form').submit()
Hope this helps!

Related

I have two models (events & artists) pagy is working fine with my artist model, but my event model isn't displaying last records

I do have a more elaborate index method in my events controller
def index
if params[:q]
params[:q][:combinator] = "and"
params[:q][:groupings] = []
split_geo = params[:q][:address_or_city_or_state_or_country_or_continent_cont_all].split((/(,\s*)+/))
split_geo.map! do |a|
I18n.transliterate a
end
split_geo.each_with_index do |word, index|
params[:q][:groupings][index] = { address_or_city_or_state_or_country_or_continent_cont_all: word }
end
end
#q = Event.ransack(params[:q])
#pagy, #events = pagy(#q.result(distinct: true))
end
In my events index page I have:
<h2>Upcoming Events</h2>
<br>
<%== pagy_bootstrap_nav(#pagy) %>
<br>
<div class="event-list-wrapper">
<% #events.upcoming_events.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
When I remove my upcoming_events scope, the records will display correctly.
In my event.rb model I have:
scope :upcoming_events, -> { where('event_start_date > ?', Time.now).or(where('event_end_date > ?', Date.yesterday)) }
Am I missing something in order to get pagy with work with my event scope?

A filtered index page via ids of has_many through child objects

I have an index page for Jobs. Both Cities and Positions has a has_many :through relationship with jobs.
On the Jobs Index Page, I have a small search form, which I would like to use to filter results by the combination of cities and Positions a user chooses.
This is how it looks so far
Jobs#Index
- provide(:title, 'All Jobs')
.thinstripe_career
.darken
.container
.row
.span10.offset1
.jobs_header
.row
.span7
h2 All #{#city.name if #city} #{#position.name if #position} Jobs
.span3
== link_to "Sign up for Job Alerts!", "#", :class => "button"
- if current_user && current_user.admin?
== render 'shared/dashboard_header'
.container
.row
.span10.offset1
.job_search
== form_tag jobs_path, :method => 'get', :id => "jobs_filter" do
h2 I'd like jobs in
.filter_sect
== select_tag :city_id, options_from_collection_for_select(#cities, "id", "name"), :class => "basic"
.filter_sect
== select_tag :position_id, options_from_collection_for_select(#positions, "id", "name"), :class => "basic"
.filter_sect.filter_search
== submit_tag "Search", :class => "button search_button button_black"
ul.jobs
== render #jobs
== will_paginate
Jobs#Index Controller
def index
#cities = City.all
#positions = Position.all
#city = City.find(params[:city_id]) if params[:city_id]
#position = Position.find(params[:position_id]) if params[:position_id]
#jobs = Job.paginate(page: params[:page])
end
I would like to #jobs to be be filtered buy #city or #position.
With the condition that if #city is not present, it only filters by #position, and vice versa.
If both are not present, then it simply paginates all jobs. However, all the code I think of is quite long and ridden with if statements, so I think I'm going into the wrong path.
How would I go about filtering #jobs through #city and #position?
You can utilize the fact that conditions in multiple where calls are joined by AND when the query is executed:
#jobs = Job
#jobs = #jobs.includes(:cities).where(cities: { id: #city }) if #city
#jobs = #jobs.where(position_id: #position) if #position
#jobs = #jobs.paginate(page: params[:page], per_page: 5)

Kaminari Pagination with Filter

I'm using Kaminari on my site with a 'load more' button to show another six items when clicked. It works great but when I try to add a sorting order it's not passing the params to the link_to_next_page def although I can see it in the html...
The other question asked on this said to pass the params to the link_to_next_page but it doesn't make a difference.
Example: When I try to sort by lowest price > highest price the first six items are sorted but on 'load more' the sorting order is random.
Can anyone advise here??
Thanks.
Some code...
index.html.erb
<div id="offers">
<%= render :partial => #television_offers %>
</div>
<%= link_to_next_page #television_offers, 'Load More', :remote => true, :id=>"load_more_link", :params => params %> </div>
index.js.erb
$('#offers').append("<%= escape_javascript(render :partial => #television_offers)%>");
$('#load_more_link').replaceWith("<%= escape_javascript(link_to_next_page(#television_offers, 'Load More', :remote => true, :id=>'load_more_link', :params => params))%>");
application_helper.rb
def link_to_next_page(scope, name, options = {}, &block)
param_name = options.delete(:param_name) || Kaminari.config.param_name
link_to_unless scope.last_page?, name, {param_name => (scope.current_page + 1)}, options.merge(:rel => 'next') do
block.call if block
end
end
television_offers_controller.rb
def index
#television_offers = TelevisionOffer.page(params[:page]).per(6)
if params[:filter] == "large_screens"
#television_offers = #television_offers.large_size
elsif params[:filter] == "small_screens"
#television_offers = #television_offers.small_size
elsif params[:filter] == "price"
if params[:order] == "asc"
#television_offers = #television_offers.asc(:offer_price)
else
#television_offers = #television_offers.desc(:offer_price)
end
else
#television_offers = #television_offers.best
end
end
For anyone experiencing the same problem this was solved by simply updating kaminari to the latest version

Search function is not working in ruby on rails

I am creating a form for my posts search. I am doing like this ....
erb form code...
<%= form_tag '/posts/search-post', :remote=> "true" do %>
<p>
<%= text_field_tag :search, params[:search], :placeholder => "Search Posts..." %><br/>
<%= radio_button_tag :day, 1, params[:day] %>None
<%= radio_button_tag :day, 2, params[:day] %>Last Week
<%= radio_button_tag :day, 3, params[:day] %>Last Month<br/>
<%= submit_tag "Search", :onclick => "document.getElementById('spinner').style.visibility='visible';document.getElementById('postlist').style.visibility='hidden'" %>
</p>
<% end %>
root.rb
match 'posts/search-post', to: 'posts#search_post'
posts_controller.rb
def search_post
if !params[:search].blank? && params[:day].blank?
#posts = Post.paginate(page: params[:page],:per_page => 5).search(params[:search])
elsif params[:search].blank? && !params[:day].blank?
#posts = Post.paginate(page: params[:page],:per_page => 5).all if params[:day] == "1"
#posts = Post.paginate(page: params[:page],:per_page => 5).where("created_at >= ?", 1.week.ago.utc) if params[:day] == "2"
#posts = Post.paginate(page: params[:page],:per_page => 5).where("created_at >= ?", 1.month.ago.utc) if params[:day] == "3"
elsif !params[:search].blank? && !params[:day].blank?
#posts = Post.paginate(page: params[:page],:per_page => 5).search(params[:search]) if params[:day] == "1"
#posts = Post.paginate(page: params[:page],:per_page => 5).search(params[:search]).where("created_at >= ?", 1.week.ago.utc) if params[:day] == "2"
#posts = Post.paginate(page: params[:page],:per_page => 5).search(params[:search]).where("created_at >= ?", 1.month.ago.utc) if params[:day] == "3"
else
end
end
Post.rb model
def self.search(search)
search_condition = "%" + search + "%"
if search
find(:all, :conditions => ['lower(content) LIKE ? OR lower(title) LIKE ?', search_condition.downcase,search_condition.downcase])
else
find(:all)
end
end
search-post.js.erb
$("#posts_list").html("<%= escape_javascript( render(:partial => "posts") ) %>");
When I search by both keyword and day type then searching is not working (Getting all post list-items). I don't know where i am wrong. Please help.
I am not sure if you've done this intentionally, but in both your elseif and else sections in your controller, you're overwriting your search results.
For example, in your else section, you first do this:
#posts = Post.paginate(page: params[:page],:per_page => 5).search(params[:search]) if params[:day] == "1"
and then you do this:
#posts = Post.paginate(page: params[:page],:per_page => 5).where("created_at >= ?", 1.week.ago.utc) if params[:day] == "2"
Which means that the second set of results that are saved in #posts will overwrite your first set of results (what was saved in #posts in your first line).
Since you're doing an "&&" operation, then you should include your result set from your first line into the second.
One solution to your problem might be to change your Post.rb model to something like this:
def self.search(search, previous_results_set)
search_condition = "%" + search + "%"
if search
if previous_result_set.nil?
find(:all, :conditions => ['lower(content) LIKE ? OR lower(title) LIKE ?', search_condition.downcase,search_condition.downcase])
else
previous_result_set.find(:all, :conditions => ['lower(content) LIKE ? OR lower(title) LIKE ?', search_condition.downcase,search_condition.downcase])
else
find(:all)
end
end
My code might not be perfect and you can probably find a more efficient way of doing it in your code, but you get the idea. Even when you user the .where, you need to perform the .where on the previous result set, not on the Post model as a whole again. That way you will be filtering your previously filtered results.
Hope this helps.

Filtering values of index page on values defined in drop down box.rails 3

I am a newbie with rails and I am trying to fliter my index page on values selected by drop down box on index page
For Eg .In my index page I am having a drop down box showing employee names if user selects a value from drop down list the values of index page should filter with that employee name.
Note- Te Employee name is a cross reference field
My Controller Look like
def index
#complaints = Complaint.paginate(:page => params[:page], :per_page => 10)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #complaints }
end
end
My Index View Looks like
<%= select("employee", "employee_id", Employee.all.collect {|p| [ p.fullname, p.id ] }, { :include_blank => true }) %>
I have tried to answer with whatever I can understand from your question and
I am asssuming u dont want filtering through an ajax call and your complaint table consists of a column named employee_id.
In your index_view add
<%= form_tag 'controllers_index_path' , :method => "get", :id=> 'filter_employees_form' do %>
<p>
<%= select_tag 'employee_id', options_for_select(Employee.all.collect {|p| [p.fullname, p.id ] }, :selected => params[:employee_id]), :prompt => 'Select', :id => 'filter_employees' %>
</p>
<% end %>
Add the following code in the javascript file or add it at the end of your index page.
$(document).ready(function(){
$('#filter_employees').change(function(){
$('#filter_employees_form').submit();
})
})
In controller.rb
def index
#complaints = Complaint.get_complaints(params).paginate(:page => params[:page], :per_page => 10)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #complaints }
end
end
In complaint.rb(model)
def self.get_complaints(params)
conditions = ['']
conditions = ['complaints.employee_id = ?', params[:employee_id]] if params[:employee_id]
self.where(conditions)
end
Hope this is what you are looking for.

Resources