Rails radio buttons checked with params - ruby-on-rails

I'm sorting through the User model on the User Index page. Right now, all I have is two options that can be accessed through radio buttons. I may be doing this the wrong way, it works for now, but if you have a better way then please shed some light. The main question I have is why are the radio buttons not checked when they are selected?
User's Index Controller
if params[:sort] == "popular"
#users = User.most_popular_users
elsif params[:sort] == "recent"
#users = User.most_recent_users
end
User.rb
scope :most_popular_users, -> do
results = select {|user| user.followers }
results.sort! {|t1, t2| t2.followers.count <=> t1.followers.count}
end
scope :most_recent_users, -> do
results = User.all
results.sort! {|t1, t2| t2.created_at <=> t1.created_at}
end
Again, I'm not sure how correct that is in terms of "best practices", so if it's wrong I would love to change it as well. Back to the question...
My view looks like this:
<%= form_tag find_users_path, :method => 'get' do %>
<%= radio_button_tag(:sort, "popular") %>
<%= label_tag(:sort_popular, "Popular") %>
<%= radio_button_tag(:sort, "recent") %>
<%= label_tag(:sort_recent, "Recent") %>
<%= submit_tag "Submit" %>
<% end %>
Right now, when you submit the form, it sorts the Users properly, but the selected radio is not selected on the respective page. So when you submit the form the find the popular users, the url looks like:
/people?sort=popular
but the radio button for popular is not checked.

You need to do something like the following:
radio_button_tag(:sort,"popular", params[:sort].eql?("popular"))
The 3rd argument for the radio_button_tag helper accepts a true or false value to know if the radio is checked or not. More info here:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-radio_button_tag

Related

Checkbox that will search DB for boolean - Rails 4

I have a search form and I need a checkbox that will select and then return whether a particular listing allows pets. I have created a custom route, controller method, and erb in the view. However, I am not accomplishing what I set out to do.
When a user clicks the Pets Allowed checkbox and then clicks search, the listings where pets allowed == true should be returned. I am not sure how to go about that.
This is the current code, but does not accomplish what I am after. This will redirect to /pets_allowed but that isn't a real thing.
listings_controller:
def pets_allowed
#listings = Listing.where(pets: true)
end
routes.rb:
get "pets_allowed" => "listings#pets_allowed"
html.erb:
<div>
<%= link_to 'Pets Allowed', pets_allowed_path, :class => 'button btn-transparent' %>
</div>
You probably need to use form_for instead of link_to.
<%= form_for :search_pets, url: pets_allowed_path, method: :get do |f| %>
<%= f.check_box :has_pets %>
<% end %>
Now in action,
def pets_allowed
#listings = Listing.where(pets: params[:search_pets][:has_pets])
end
When the checkbox is unchecked, it will return all the listings with no pets and when its checked it will return all the listings that have pets.
Hope that helps!

Does select_tag always have to return something?

I have two forms that leads to one controller action:
<%= form_tag some_action_path do %>
<%= slect_tag 'foo[]', options_for_select([
["Nothing", nil],
["wal1", "wal1"],
["wal2", "wal2"]]) %>
<%= submit_tag "Search" %>
<% end %>
<%= form_tag some_action_path do %>
<%= check_box_tag 'foo[]', "wal1" %>
<%= check_box_tag 'foo[]', "wal2" %>
<%= submit_tag "Search" %>
<% end %>
My problem is that when I select "Nothing" in select select_tag I get [""], on the other hand when I submit second form without any check_box selected I get nil. Which gives me a headake in my search function. Because it have to look like this:
def search_action(foo)
if foo.nil?
Obj.all
elsif foo.present? && foo[0].blank?
Obj.all
elsif foo.present? && foo[0].pesent?
Obj.where(foo: foo)
end
end
The function above is irrelewent, I only wanted to show how the difference output between those two forms complicate my search action.
My question:
Is there any way to return nil from "select_tag" form? Or I am stupid to lead two forms to one controller action and one search method, and I should write two actions with two search action that leads to one view. :D
Usually the search functionality is in one form where you have the both options available, but there is nothing wrong with your approach if you want them to be separate searches. Though I would rename the input of either of the forms to not be same as the other forms inputs to differentiate them on controller and then be able to write something like
def search_action(foo)
if form_1_attribute.present?
Obj.where(form_1_attribute: form_1_attribute)
elsif form_2_attribute.present? && form_2_attribute.blank?
Obj.where(form_2_attribute: form_2_attribute)
else
Obj.all
end
end

rails 3.1 select_tag usage

Ive got a select_tag field at the top of a page and trying to get the selected option to change the content on the page based on the users selection.
Im a learner and have found pieces of information around but without detailed examples and good explanations on how to best approach and implement.
The scenario is as follows:
I have a belongs_to association between a project and documents and in one of my views which lists documents, I want to only show all the documents that belong to the currently selected project in the select tag.
Passing the selected project's id to the documents index action which only shows documents for a specified project id via a link_to tag came to mind. This would thus refresh the page with the correct documents in the view but I believe that is not the correct way to do it and that I cant use link_to tags as options in a select_tag. Can anyone help and offer an example?
I would suggest using the form.select method and options_for_select as in
f.select :attribute, options_for_select(#array, default_value)
and in your controller you should create or update using the submitted parameter
n = record.new(:attribute => params[:attribute])
have fun
In your controller:
def index
if params[:project]
#documents = Document.where(:project => params[:project]
else
#projects = Project.all
end
end
In your form/view:
<%= form_tag 'projects', :method => :get do %>
<%= options_from_collection_for_select(#projects, :id, :name)
<%= submit_tag %>
<% end %>
<% if #documents %>
<%= #documents.each do |d| %>
....
<% end >
<% end %>

Help with checkboxes

When a user submits without any boxes checked. I need my ODM (Mongoid) to update the record appropriately.
Having a bit of trouble with:
<% Notification.all.each do |notification| %>
<li>
<%= check_box_tag 'user[notification_ids][]', notification.id, #user.notifications.include?(notification) %>
<%= label_tag notification.description %>
</li>
<% end %>
The doc suggests that the check_box helper puts in a hidden input. The hidden field has the same name and its attributes mimic an unchecked check box. However, with the above code. I am going through a loop. Which is slightly different.
I tried:
<%= check_box('user_notification_ids_', '', options = {:index => notification.id, :checked => #user.notifications.include?(notification)}, checked_value = "1", unchecked_value = "0") %>
But whenever I submit, I get: illegal ObjectId format
Or should I create the hidden tag for notification_ids manually? Something like:
<%= hidden_field_tag 'user[notification_ids][]', '[]' %>
Looking to hear your feedback
Go with the first loop you included. It looks much simpler and looks like it does the same thing.
If I understand your first sentence correctly, it sounds like you aren't seeing the user's notifications getting updated to none when they uncheck all the check boxes. When there are no check boxes checked, the browser won't send that param back. It simply won't be included in params so when you do something like:
#user.update_attributes(params[:user])
... notifications won't get updated. In your controller, do this to ensure there is something set for params[:user][:notifications]:
params[:user][:notifications] ||= []
This is will set it to an empty array if there if it doesn't exists and/or there's no value there. This ensures that update_attributes will set it to none/empty.
check_box_tag doesn't generate any hidden field. check_box does, but looking at your situation, I think using check_box_tag is more appropriate since the check_box method is mainly used for boolean field. Here is one way to do it.
<%= hidden_field_tag 'user[notification_ids][]' %>
<% Notification.all.each do |notification| %>
<li>
<%= check_box_tag 'user[notification_ids][]', notification.id, #user.notifications.include?(notification) %>
<%= label_tag notification.description %>
</li>
<% end %>
When the form is submitted with the checkboxes for Notification of id 2 and 3 checked, the value for params[:user] is { "notification_ids" => ["", "2", "3"] }. When nothing is checked, params[:user] is {"notification_ids"=>[""]}, which will clear the user's notifications. This works because empty string is ignored by ActiveRecord. From here, we can use the usual #user.update_attributes(params[:user]) to update the User model.

ruby on rails will paginate between dates

In the application there is a default report the user see's listing all the calls for a certain phone. However, the user can select a date range to sort the list from. Doing that, everything works correctly, but when the user selects the date range and changes to the second page, the date-range is lost and it goes back to the default view for the second page.
In my controller, I'm checking to see if the date_range param is being passed in. If it isn't, I display the entire listing, if it is, I display the records in between the certain date range.
The problem is, when I click on a new page, the new parameter doesn't include the old date-range that it should.
How do I go about doing this, I was thinking of doing some class level variable test but that isn't working out the way I thought. And I'm pretty stuck.
I don't have the code right in front of me, but if I remember correctly it's something like this:
<% form for :date_range do |f| %>
<%= f.calendar_date_select :start %>
<%= f.calendar_date_select :end %>
<%= f.Submit %>
<% end %>
And in the controller, it's something like:
if params[:date_range] == nil
find the complete listings without a date range
else
find the listings that are within the date range
end
The main problem is that you're using a POST request when submitting the form, but will-paginate uses a GET request. You should also use form_tag instead of form_for because form_for will nest the fields in a hash which is not possible with GET.
<% form_tag items_path, :method => 'get' do %>
<%= calendar_date_select_tag :start_date %>
<%= calendar_date_select_tag :end_date %>
<%= submit_tag "Submit", :name => nil %>
<% end %>
Then check params[:start_date] and params[:end_date] directly. You'll need to change items_path to whatever page you want the form to go to.
This is untested but it should get you in the right direction.
You could modify the link_to (assuming that's how you go through pages) so that it passed the date_range param.
= link_to 'Next', #whatever_path, :date_range => #date_range
where #date_range could be set in your controller by capturing your params in an instance variable.. .
But there may be a better solution.

Resources