Checkbox that will search DB for boolean - Rails 4 - ruby-on-rails

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!

Related

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

Select_tag login

I would like to have a drop down menu with a list of all the user names in the db. From there, I would like the user to choose his/her name and be able to click login and be taken to their respective page. At this point, a password is not needed. Currently, I have the following:
controller:
def login
#user = User.new
#users = User.all
# #user = User.find_by_id(:id)
# redirect_to user_path(#user)
end
view:
<%= form_for #user, url: '/login', html: {method: 'get'} do |f| %>
<%= f.label "Name" %>
<br/>
<%= select_tag :user, options_for_select(#users) do |users| %>
<%= link_to users.name, users %>
<% end %>
<br/>
<br/>
<%= f.submit 'Login' %>
<% end %>
I cannot seem to link the user to their path and also, i want to show the users name in the drop down menu. Currently, it shows a hexidecimal pointer.
Thank you in advance.
You shouldn't be making a new User object here: you just want to load one out of the database. What you want to do in the controller is just to set current_user to be one of the existing users, right?
Also you've got the form submitting back to the action which loads the form in, which seems weird. I would make it submit to a new action, like "set_current_user" which is a POST action.
in your login template:
<%= form_tag '/set_current_user' do %>
<%= f.label "Name" %>
<br/>
<%= select_tag "user_id", options_for_select(#users.collect{|user| [user.name, user.id] } %>
<br/>
<br/>
<%= submit_tag 'Login' %>
<% end %>
in the controller (you'll need to amend routes.rb to make the '/set_current_user' go to this action) you then need to set something which will keep the user logged in. The traditional way to do this is via session[:user_id], and to have a method current_user which uses this.
def set_current_user
session[:user_id] = params[:user_id]
redirect_to "/" and return
end
Your initial approach is reminiscent of how this sort of thing is normally handled, wherein you do have a form_for, but it's for a UserSession object rather than a User object.

Rails radio buttons checked with params

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

Rails Controllers - Adding a Custom Action

I have an Article resource and have defined resourceful routes for it. I want to create a simple page that shows the articles of the current user. I am aware that it is possible to do so by adding another action, for example 'search' to articles controller which will contain the custom code that searches for articles that have the same user id. And for the routes:
resources :articles do
get 'search'
end
But I'm not sure if adding a custom action is a good idea in this case. I'm thinking I can still use the index action (which shows all articles) and pass some sort of parameter from the url so that it can distinguish if the user wants to see all articles or just his own. But I'm not sure exactly how this can be done. Any help would be great. Thanks!
You can use the query string to pass parameters. see here
So you can pass something like .../articles?user_id=2
In your controller, just change the behavior according to the user_id parameter.
you don't need to create a new action/view for it.
You can add a small form to filter all articles or only my articles, for example:
<%= form_tag articles_path, method: :get do %>
<%= radio_button_tag :search, "all", :checked => true %>
<%= label_tag :all %><br />
<%= radio_button_tag :search, "my" %>
<%= label_tag :my_articles %><br />
<%= submit_tag "filter", name: nil %>
<% end %>
than in your controller:
def index
if params[:search] == 'my'
#articles = current_user.articles
else
#articles = Article.all
end

How to use link_to to pass value back to a search field and execute in RAILS, RoR?

I have a search field and button. When the user searches something like "cat" my view renders a bunch of related keywords such as "catnip", "cat toys", "cats" etc... each of these results are links, and are to pass the value of the string displayed back into the search to generate results for the selected link. For example:
User renders search page and searches for "cat"
view page renders results related to "cat" such as "catnip" "kittens"
User now clicks on "catnip"
View page renders results related to "catnip" such as "grass"
Is this possible with link_to? I'm lost and not quite sure what to do...
--
My Code:
SEARCH VIEW PAGE
<% form for(:search, url => search_path) do |f| %>
Search: <%= f.text_field :search %><br>
<%= f.submit "Search Keyword" %><p>
<% unless #keywords.nil? %>
<h3>Keyword Results</h3>
<% #keywords.each do |k| %>
<%= link_to k.name, :controller => "search", :action => "keywords", value => k.name %>
<% end %>
SEARCH CONTROLLER
def keywords
if request.post? then
#keywords = googlesearchapi(params[:search])
end
I want to pass the link_to value that the user clicks on as the :search parameter... thanks in advance for any advice~~
First of all, you want the link to be: "../search/keywords?search=catnip", to do this, modify the link_to as:
<%= link_to k.name, :controller => "search", :action => "keywords", :search => k.name %>
Then, you need to delete the line if request.post? then, otherwise it won't handle the requests coming from link_to, as it is a GET request (not POST).

Resources