Rails 3: How do I mix form params and URL params? - ruby-on-rails

I am working on a legacy app and am trying to upgrade it to Rails 3. Currently when I do a search I get the URL: http://localhost:3000/search/external_search/?keyword=argentina. However, when I try to filter out the results, I get http://localhost:3000/search/external_search/?order=Name:ASC, without the keyword parameter in the URL. Since there wasn't a keyword params, the filter wouldn't work. This was messing up my filter, so I decided to add a hidden field tag
<%= hidden_field_tag 'keyword', #search.text %>
which makes it work, but the URL didn't change. I want it to look like:
http://localhost:3000/search/external_search/?keyword=argentina&order=Name:ASC
Where exactly would I accomplish this? In the controller or the form?

If you want to see the parameters of the submited form in the URL, you must use GET method instead of POST.
Add the option :method => :get to the form_for or form_tag enclosing the <%= hidden_field_tag 'keyword', #search.text %>

Related

Rails form_with defaulting to incorrect method

I'm using Rails 6. I have a route that defines a get request:
namespace :admin do
get '/machines/search', to: 'machines#search', as: 'search_machines'
end
Then, I have a form_with that sets the url to the route. When the form is loaded, the HTML that's generated for the form contains a method="post" instead of method="get" which is what I would've expected since the route is a GET request and not a POST. I can add the method: "get" parameter to the form_with and this fixes the issue but I don't understand why Rails didn't pick up the correct method initially.
<%= form_with url: admin_search_machines_path() do |i| %>
<%= i.text_field :q, placeholder: "Search", autocomplete: "off", class: "debounce-form-submit form-control" %>
<% end %>
According to the documentation form_with does default to POST if method is not specified. Which is not 100% correct, as it will switch to PATCH (via hidden field trick) if the model is persisted (source).
Up to today, the code does not look at the route itself to specify the method.
I think the (backwards incompatible) automagic you suggest is not totally off, though. You might ask about that in the rubyonrails forums and get feedback whether this would be a welcomed change. Personally, I never expected it to inspect the route. Also, you might have the same route with post and get methods, which would make lookup more involved than what meets the eye on first sight.

Ruby on Rails get paramenter from URL on View

I'd like to get the paramenter from the URL on my view/html.
For example, I'm showing an specific item from my data base, and the URL is like this: "http://localhost:3000/menus/index.%23%3CMenu::ActiveRecord_Relation:0x007f50ed153250%3E?id=6"
What I want is: when I click on the New Button of that specific item, the form opens with the URL "http://localhost:3000/menus/new", but I want somehow pass that id=6 to this NEW view.
I am using this code on the html to open the form: <%= link_to 'Novo', new_menu_path %>
I also tried: <%= link_to 'Novo', new_menu_path(#menus, :id) %>, but the id param is always null/empty.
How do I do that?
Thank you
To pass an extra param to an url when you define a link_to
<%= link_to 'Novo', new_menu_path(id: #menu.id, other_param: "hello") %>
will generate http://localhost:3000/menus/new?id=6&other_param=hello
this will add the following to the params hash
Parameters: {"id"=>"6", "other_param"=>"hello"}
well :id is just a symbol, you need to tell the route helper what to bind to it. For example
<%= link_to 'Novo', new_menu_path(id: params[:id]) %>
which should give you something like /menus/new?id=6

rails 3 form_tag method: :get to include only the fields that were changed

I'm writing a search form that will reload the page adding to the URL the search parameters.
Currently the URL generated by my form contains all the form fields, including the empty ones. This clutters a lot the url generated with data that is often not needed.
I would like my form to redirect to an url that only has the fields that contain data.
There's the code for my form:
= form_tag orders_path, method: :get do
= text_field_tag :search, params[:search], class: "span2 appendedInputButtons"
= select_tag "order_types",
options_from_collection_for_select(OrderType.all, :id, :name),
multiple: true,
size: 8,
include_blank: "select"
%button.btn.btn-primary Update list
When I hit the submit button without filling any of the form I get redirected to an url like this:
http://localhost:3000/orders?utf8=%E2%9C%93&search=&order_types%5B%5D=
while I would like the url to be like this:
http://localhost:3000/orders
and if I select only some of the order_types I get:
http://localhost:3000/orders?utf8=%E2%9C%93&search=&order_types%5B%5D=3&order_types%5B%5D=6
while I would like it to be like:
http://localhost:3000/orders?order_types%5B%5D=3&order_types%5B%5D=6
or even better:
http://localhost:3000/orders?order_types=3,6
or something similar, but more concise,
Thanks a lot for any help,
form_for binds the form to an object and rails internals will namespace the fields related to this object (or objects) with a prefix, so that when the form is submitted the data will appear in params as params[:prefix][:some_data].
To reduce the size of the query string I would suggest you to use form_tag and build the form manually. In this way you can have full control over the submitted fields and also avoid the utf8=%E2%9C%93 utf8 enforcement snowmen hack.

How to pass the UI control values as the parameters to the Controller in Rails?

I met a problem of parameter passing in Rails.
I have an object named 'account' and another object named 'locale'. There is a one-to-many relationship between them. One locale can be mapped with multiple accounts.
On accounts/index.html.erb, I have a dropdown which will list all the available locales.
And I have a link below.
In expectation, when I clicks this link, the index method of account controller will be called and the value of selected locale id will be passed. And the index method will retrieve all the accounts belonging to that locale.
What blocks me is I have no idea how to pass that selected value of dropdown to the controller.
I only know the basic way of passing a parameter is:
<%= link_to 'Refresh', {:action => 'index', :fromvar => 'refresh', :selected_locale_id => '1'}.
And from controller, we can get it by:
params[:selected_locale_id]
But it is the case of a fixed value. How to deal with a dynamic UI control value as my case?
Does link_to support some javascript to be embedded?
My rails version is 3.2.13.
Any one has idea on this?
You can either do this as a form, or as javascript in the onclick event of the link. I would recommend a form.
The following should get you started:
<%= form_for :index do |form| %>
<%= form.select :locale_id, Locale.all %>
<%= form.submit %>
<% end %>
Be sure to add a post route to the index action to allow the form to submit.

routing scope problem with form_for (partial)

Trying to route:
scope :shortcut do
resources :text_elems
end
Using basic scaffold with form partial
*_form.html.erb*
<%= form_for(#text_elem, :shortcut => #shortcut) do |f| %>
...
Problem is: When I call the edit action, the form html shows as:
<form ... action="/25/text_elems/25">
Note: The new action renders the form action correctly:
<form ... action="/home/text_elems">
So it appears that my :shortcut param is getting trumped by the :id param when form_for processes it's block. Now I am able to get the action to correctly route with the :shortcut param if I manually make the :url => {...} in the form_for block, but I would prefer to keep the code dry, plus I want to report this problem to rails if it is indeed a bug.
Can anyone else confirm this as a bug?
Actually, you can pass the values as a full hash, rather than trying to rely on the default to_param (which is what gets called if all you do is pass the #text_elem)
<%= form_for({:id => #text_elem.to_param, :shortcut => #shortcut}) do |f| %>
however, if this is actually a nested-resource, you could also do:
<%= form_for([#shortcut, #text_elem]) do |f| %>
I was having the same issues and none of the above answers helped.
The last answer on this page worked for me though...
https://rails.lighthouseapp.com/projects/8994/tickets/6736-problem-with-scoped-routes-and-form_for-helper

Resources