Routing rails Simple Search to a listings page - ruby-on-rails

I have implemented a simple rails search which is searching my DB and displaying the results just fine. However, I am not fully understanding how to route my search query to a new page.
I have used rails scaffolding to create this particular section of my site:
class DogSearchesController < ApplicationController
before_action :set_dog_search, only: [:show, :edit, :update, :destroy]
# GET /dog_searches
# GET /dog_searches.json
def index
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
# GET /dog_searches/1
# GET /dog_searches/1.json
def show
#dog_search = DogSearch.find(params[:city])
end
index.html.rb
<%= form_tag dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
I have created a page in dog_searches/listing and added this to my Routes file as get 'dog_searches/listing'
Any help would be appreciated.

Commonly, search results will go to the index page with params. If you ever want to show a list of dog_searches, filtered or paged, it's a common approach to use the index action and view for all of this.
But, that said, if you want to render the listing page, you may want to set the form to that page
# routes.rb
resources :dog_searches do
get :listing, :on => :collection
end
In the view - notice the url change
<%= form_tag listing_dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
Then in the controller, you'd have a very similar action to index.
def listing
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
But again, can index handle all of this for you instead?

What is the directory where your form is, and which new page do you want to route your search query or result to?
By default, rails render the file with the same name as the controller action.
Therefore, if the controller action that is doing the search is the index action in DogSearchesController, then the view file is the dog_searches/index.html.erb
On the other hand, if you want the view to be dog_searches/listing.html.erb, then you may want to create a listing action in the DogSearchesController and move your search inside it as follow:
def listing
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
and let your search form point to this action:
<%= form_tag listing_dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
Note here that I'm assuming that the path to the listing action is the listing_dog_searches_path.
Hope this throws some light into it?

Related

Rails - Is there a way to autocomplete with form_tag attribute?

My search bar is using a form_tag type, and I can search and enter and it will show results, but it will not give autocompletion or suggestions when typing in the search bar.
When the user starts typing, I want it to display usernames.
Here is what I have tried:
This view is my application.html.erb and it is on my navbar. I dont know if that is also important.
<%= form_tag users_path, :autocomplete => "on", :method => 'get', :id => 'users_search' do %>
<%= text_field_tag :search, params[:search], placeholder:"search members..",style:"width:300px; height:35px;"
%>
<%= submit_tag "", :name => nil, :style => "display: none;" %>
<% end %>
I also tried :autocomplete => :on in the text_field_tag. I'm just not sure how to go about this using form_tag.
Here is the rest of my code that may be important:
User_controller.rb
def index
#users = User.search(params[:search])
end
User.rb
def self.search(username)
if username
username.downcase!
where("username LIKE ?","#{username}%")
else
all
end
end

Rails 5: Two search form_tags on the same page

I'm trying to implement a two search form_tag on a the same page, each search form is placed inside dynamic bootstrap tabs. The first one which is working is basic a search form with one field. The second one which is not working has two fields, one is the same search method as the first and the other I'm trying to get the address from the other_location field and via params[:other_location].
With the current setup the other_location field form the second form does not appear!
Both of the forms are inside partials and I am rendering them inside two dynamic bootstrap tabs like this:
<%= render 'pages/search' %>
<%= render 'pages/search_other' %>
<%= form_tag search_items_path, :method => "get" do %>
<%= text_field_tag :search, params[:search], autofocus: true,
class: "search-query search_size",
placeholder: "Enter product to search" %>
<%= submit_tag "Search", name: nil, :style => "display: none;" %>
<%end%>
<%= form_for :search_other_path, :method => "get" do |form| %>
<%= form.text_field :search, autofocus: true,
class: "search-query search_size",
placeholder: "Enter keyword to search" %>
<% form.fields_for :other_location_path, :method => "get" do |f| %>
<%= f.text_field :other_location, class: "search-query search_size",
placeholder: "Enter address to search" %>
<%= form.submit "Search", name: nil, :style => "display: none;" %>
<%end%>
<%end%>
model
def self.search(search)
return where("0=1") if search !~ /\w{4}/
where("lower(title) LIKE lower(:term)", term: "%#{search}%")
end
routes.rb
get 'search' => 'pages#search', as: 'search_posts'
get 'search' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#other_location', as: 'other_location'
controller:
def search_other
if params[:search]
#posts = Post.near(other_location,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
def other_location
other_location = params[:other_location]
if params[:other_location]
Geocoder.search(params[:other_location])
end
end
def search
if params[:search]
#posts = Post.near(action,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
On your route file:
get 'search/other' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#search_other', as: 'search_other_items'
both GET requests are going to your pages_controller.rb #search_other method. So even if you have the two form_tags sending the data to different paths (search_other_path, and search_other_items_path) it would be going to the same controler method - which is redundant.
On your actual HTML you have two form tags:
<%= form_tag search_items_path, :method => "get" do %>
and
<%= form_tag search_other_items_path, :method => "get" do %>
You have not mentioned search_items_path in your routes, so I have no idea where that's pointing to. Likely its a proper controller that works since you mentioned the first form was the only one working.
Now, your mentioned controller only has a search method. So to start you are looking at the wrong controller. You should be looking at the controller methods being referenced by the form's action.
In this case, the second form is sending it's request to search_other_items_path which according to your routes, its pointing to pages_controller.rb -> #search_other method.
You should edit your question to include code that is actually relevant. Maybe then I can actually help.

Do not post a form in a Rails root route

I have a controller with just one method:
index_controller.rb
def index
# some code
end
The form:
index.html.erb
<%= form_tag :class => "form-inline signup" do %>
<div class="form-group">
<%= text_field_tag :url, nil, :class => "form-control", :placeholder => "URL do tópico" %>
</div>
<%= submit_tag "Enviar", method: :post, :class => 'btn btn-theme' %>
<% end %>
And a simple root route:
root 'index#index'
post '/', to: 'index#index'
The problem is that when I load the root page, the form is posted automatically, when the preferable was to POST just on the button call.
What am I missing here?
You should move the code for the post out to another action that can handle that.
post '/', :to => "index#submit"
Then you can define a submit action within your IndexController to handle the form, and the index action won't run the form code anymore.

Rails 3: Can't add correct route to legacy code

Believe you can help me.
I'm trying to add new functionality to legacy code (Typo). But it seems that there is some problem about routing.
In the project routes are generated the following way:
%w{advanced cache categories comments content profiles feedback general pages
resources sidebar textfilters themes trackbacks users settings tags redirects seo post_types }.each do |i|
match "/admin/#{i}", :to => "admin/#{i}#index", :format => false
match "/admin/#{i}(/:action(/:id))", :to => "admin/#{i}", :action => nil, :id => nil, :format => false
end
My functionality is about merging articles. For that I've added new action in the /admin/content controller:
def merge
#some code here
end
A piece of a view partial (_form.html.erb) added by me:
<% if current_user.admin? and !#article.id.nil?%>
<div class=''>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %><%= text_field_tag :merge_with, nil, :size => 20 %>
<%= button_to 'Merge', admin_content_merge_path(:id => #article.id) %>
</div>
<%end%>
This partial is rendered by another partial (_edit.html.erb)
<%= form_tag(form_action, :id => "#{form_type}_form", :enctype => "multipart/form-data", :class => className) do %>
<%= render :partial => "form" %>
<% end %>
And finally _edit.html.erb is rendered by view new.html.erb
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
The problem is how to write a correct route for the controller action above which will allow me to render an edit page containing newly merged article. I wrote:
match "/admin/content/merge/:id" => "admin/content#merge",:as => 'admin/content/merge'
rake routes output:
admin_content_merge /admin/content/merge/:id(.:format) {:controller=>"admin/content", :action=>"merge"}
But the new or edit action is being invoked as I can see.
Apparently, my route is wrong, isn't it?
Could you please help me with this.
Thanks in advance!
Update
Up-to-date new.html.erb:
<% #page_heading = _('New article') %>
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
<% if current_user.admin? and !#article.id.nil?%>
<%= form_tag "/admin/content/merge/#{#article.id}" do %>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %>:
<%= text_field_tag :merge_with %><br />
<%= submit_tag "Merge" %>
<% end %>
<% end %>
Read the hint from the course:
HINT:Nesting is invalid in HTML.
That means that you can't nest form tags, don't put the form tag in another form tag, your nested form wont be able to do a correct action.
Since you have to put your code at the end of the page, try and see how to do it with having your merging form tag below the main edit article form tag. So basically you can find where the big form tag ends and put it below it.
Try to see if you can figure it out, and if not, don't hesitate to ask :)
Btw. I think everybody had some problem with this

Rails : Linking an anchor from a different controller/view

<%= link_to (:controller => "company_stuff", :action => "index", :anchor => :menu), :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
I am having difficulty linking a page which is on a different controller and also the link is an anchor. Basically the controller is called company_stuff the action is index and the anchor is called #terms
The problem was that the :controller :action :anchor was not being passed through as a hash, separate from the CSS class
Below is the solution
<%= link_to "Terms Of Use", {:controller => "company_stuff", :anchor => "terms"}, :class => "links" %>
I believe you can try something like this
<%= link_to index_company_stuff_path + "#terms", :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
Or
<%= link_to index_company_stuffs_path + "#terms", :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
Depending on your controller name and route.
You can find more information on this question How to create an anchor and redirect to this specific anchor in Ruby on Rails

Resources