Route to Current Rails page for search - ruby-on-rails

I have a sidebar that fetches articles in my application_controller but I want to add a search function to it so I modified it to look like this
def fetch_articless
#articles = Article.search(params[:search])
end
The search works fine, but I currently have my form submitting to my application root so if you search, it always redirect to the root.
<%= form_tag root_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :title => nil %>
</p>
<% end %>
Since my sidebar is on every page I would like to be able to submit my form to whatever page I am currently on and the search would be performed through the application helper. I assume I need to make a new route but being new to Rails I don't really understand how routes work yet.
Any help is greatly appreciated.

the method url_for will return the current url. And, you can always use '' (empty string) for the form action to submit to the current page
Note - with search boxes, I tend to use the <form> tag (no erb) so it doesn't include the special character (it's a snowman*), and I use a regular input submit tag so it doesn't submit the name=value of the button.
What is the _snowman param in Ruby on Rails 3 forms for?

Related

How does form_for knows what URL/path to go when the submit button is clicked?

I'm creating a scaffold named User. I checked the code of the partial view "_form" and I see the code snippet below:
<%= form_for(user) do |f| %>
<div class=field>
<%= f.label :firstname %>
<%= f.text_field :firstname %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
So if you click the submit button generated by the code above, how does rails know what URL/path to go since it didn't specify there what path to look for?
Apart from Amr El Bakry's answer, let me help you demystifying the Rails magic behind the form_for helper method.
So your question is basically: how does form_for find out the route to submit to and how does it distinguish between creating/updating the record?
Rails actually sorts this out through record identification. An example is worthy at this point:
## Creating a new user
# long style
form_for(#user, url: users_path)
# short style - record identification gets used
form_for(#user)
## Updating an existing user
# long style
form_for(#user, url: user_path(#user), html: { method: "patch" })
# short style - record identification to the rescue
form_for(#user)
You can clearly see that the short style is the same for both cases.
Record identification is smart enough to figure out if the record is new or an existing one by invoking #user.persisted?.
You may be interested to assert this fact yourself in the form_for definition inside the form_helper.rb on line 462 !
Hope it helps!
In your config/routes.rb file, you'll find Rails has added resources :users when you generated the scaffold. This is called a resourceful route, and it creates seven different routes for your user resource; each route maps an HTTP verb and a URL to a controller action.
In your case, when you submit the form, the HTTP verb is POST, the path is /users mapped to the create action inside the users controller. This is Rails default and you can read all about it in the Rails Guides on Routing.

rails how to show a search result based on current locale

Rails app is detecting the different locale from pages and displaying correctly except in the results from a search form in index page.
my routes:
get 'search' => 'mymodel#show'
my controller:
def search
if #mymodel = mymodel.find(params[:id])
else
redirect_to mymodel_path
end
end
my search partial (one for each locale and detecting correctly):
<div class="actions"><br>
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "") %>
<%= text_field_tag(:id) %>
<%= submit_tag("Search") %>
<% end %>
Search shows correct results but always in default locale "english".
It does not detect the current locale being used.
I have different show pages based on locales. They work correctly throughout the application except in displaying results from the search form.
How to display the results in the correct locale?
Thanks for any help, i can't figure out how to do this....
In your routes.rb file change the search methods route like the following:
scope "(:locale)" do
get 'search' => 'mymodel#show'
end
I managed to do it creating a new view, a new action and a new route for each locale.
So I now have a different partial, view, route and action for each locale.
Definitely not the dry way but it works.
Emu's solution works if you change
<%= form_tag("/search", method: "get") do %>
to
<%= form_tag("/"+I18n.locale.to_s+"/search", method: "get") do %>

edit form submitting to the wrong url and remote: true failing to be picked-up

This has been driving me nuts because it doesnt seem to make any sense.
I want to do something relatively simple.
Display an edit form in a modal on the index page.
I have the following code looping through a collection of sites
<%= render(#sites) %>
<%= will_paginate #sites %>
Within the sites partial i have the following form hidden away
<%= simple_form_for site, remote: true do |f| %>
<%= f.input :name %>
<%= f.input :matter %>
<%= f.submit "Save", :class => "button gr thirt", id: "site_save" %>
<% end %>
instead of generating the expected HTML i get the following, linking to the show action, am I missing something fundamental here?
<form accept-charset="UTF-8" action="/sites/1" class="simple_form edit_site" data-remote="true" method="post" novalidate="novalidate">
</form>
I was looping through a collection of #sites, a results returned by a call to Site.all
so the object being served to the above form is one of the |site|'s contained within #sites
If you serve a form_for form with a an object retrieved from the database or a 'new record' object like Site.new, it will automatically differentiate and modify the route etc accordingly between the create and the update action.
The site object contained in the #sites block was not recognizable by the form_for. So a quick re factor to request an edit from via ajax, and provide the form with the instance variable created by the edit action (#site = Site.find(params[:id]) ) was recognizable by the form_for helper and meant that the submit action, accordingly adjusted to the correct route.

Rails query string in URL?

I have a single text box form on my home page (/).
Right now the way my Rails routes is set up, when I submit this form, it takes me to /search, but it doesn't publish the query string in my url.
In other words, when I enter in "hello" in that form and press submit, I want to end up at "/search?query=hello". I know that "hello" is in params[:query], but how do I get Rails to publish that query string in the landing page URL after I submit the query?
I read the Rails routes guide but that talks about incoming query strings in the URL, not Rails publishing the URL with the query string visible.
Thanks.
My form tag so far:
<% form_tag(:controller => "search", :action => "search", :method => :get) do %>
<%= text_field_tag 'query' %>
<%= submit_tag "Search"%>
<% end %>
If I do this, I get /search?method=get, but what I would like to see is /search?query=foo.
You just need define a form with get method instead of post
<% form_tag search_url, :method => :get do %>
<%=text_field_tag :search %>
<%= submit_tag %>
<% end %>
Make sure that your form's method (as shown in the HTML page that a client would see before submitting the form) is GET not POST. With POST, the params[:query] is hidden from the user (this is often used for login forms, forms that would submit credit cards or other sensitive information). But if you want the query to show in the URL, you need to use the GET method. Rails itself isn't responsible for this behavior, it's all on the web browser's side.

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