Form with custom url keeps submitting to Create method - ruby-on-rails

I'm trying to build a simple form that passes a few params to a controller.
Here's what I have:
<%= form_tag({url: order_pizza_path}, method: :post) do %>
<%= hidden_field_tag :id, value: 0, name:"tag-1" %>
<!-- hidden field is then filled in with js -->
<%= submit_tag "Submit" %>
<% end %>
<!-- routes: -->
get 'pizza/new' => 'pizza#new', as: 'new_pizza'
post 'pizza' => 'pizza#create', as: 'create_pizza'
post 'order_pizza' => 'pizza#order', as: 'order_pizza'
But when I submit, it keeps trying to point to the Create method in my Pizza controller. I keep getting the following error:
ActionController::ParameterMissing in PizzaController#create
param is missing or the value is empty: pizza
The form's url is /pizza. This is the url of the error: /pizza?method=get&url=%2Forder_pizza
This happens even if I change it to a GET request not POST. Why does my browser keep trying to go to the Create method?

The correct syntax is
form_tag(order_pizza_path, method: :post)
not
form_tag({url: order_pizza_path}, method: :post)
{url: order_pizza_path} is not a valid url_for_options so the form_tag will submit to the default, which is the create action.
A valid value for url_for_options would be
{action: 'order'}

Related

How to build a rails form with a single parameter to flat hash

I have a rails-simpleform that looks like this:
=simple_form_for :search, url: search_path(:search), method: :get do |f|
= f.input :q
= f.submit 'Search'
When I want to retrieve the input I have to access it with:
params[:search][:q]
Is it somehow possible to build the form in a way, that the parameters aren't nested under params[:search]? So that I can access them directly through params[:q]? I understand that this only makes sense if there is only a single input for a form.
CONTEXT:
What I'm trying to do is to allow the user to either search through the search-form described above or through a short-url(myapp.com/search-text).
form_for (or simple_form_for) creates a form associated to a model object. The params passed to the controller add the model name as a key in the hash (params[:search][... fields_in_the_form ...]).
form_tag simply creates a form and it is not associated to any model. It does not add any key to the params hash except for the fields in the form. So this is a usual method to create search forms.
<%= form_tag(search_path, method: :get) do %>
<%= text_field_tag :term, params[:search] %>
<%= submit_tag 'Search', name: nil %>
<% end %>
Then you can use params[:search] in the controller.
Finally, to use myapp.com/search-text you should use route globing (http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments) defining your route as:
get '*search', to: 'static_pages#search'
The StaticPagesController#search method will receive params[:search] with anything after myapp.com/. Note: this should be your last route, as it matches anything.

Rails button_to with image and actions

I want to show button with image.
I have this code
<%= image_submit_tag "down.png", controller: "posts", action: "votedown", post_id: post.id, topic_id: post.topic_id, class: "xta" %>
Its visible properly but not calling action "votedown"
In my routes I have
post '/votedown', to: 'posts#votedown
Please also suggest if there is any other way to call the method votedown with params and image "down.png"
image_submit_tag must be used in conjunction with a form - it works just a normal html <input type="submit"> button.
You might also want to change your route definition into something more restful:
patch '/posts/:id/votedown' => "posts#votedown", as: 'votedown_post'
This makes it more apparent that this route acts on a post - and we use the PATCH method since we are changing a resource instead of creating a new resource.
Armed with our new route we can simply create a form:
<%= form_for(#post, url: votedown_post_path(#post) ) do |f| %>
<%= image_submit_tag "down.png", class: "xta" %>
<% end %>
Note that you do not need to add an input for the post id since it will be available as params[:id].
Another way to do this would be to use Rails unobstructive javascript driver to create a link or button which sends a PATCH request to '/posts/:id/votedown'.
<%= link_to image_tag("down.png", class: "xta"), votedown_post_path(#post), method: :patch %>

Form with method: "get" makes a POST request?

This is my form:
<%= form_tag(method: "get") do %>
<%= submit_tag("Submit") %>
<% end %>
When I submit this form I get a server error because there is no POST action for this URL. In my routes I have an action for GET, but it's not picked up. The error goes away when I assign an action to POST at the same URL as the GET. What am I doing wrong?
Like the comment above says, you'll need to add a path to the form, so it would look something like this...
<%= form_tag whatever_the_current_page_is_path, :method => :get %>

Passing an extra param when submitting form generated with form_tag

I have a form:
<%= form_tag(example_path, method: :get) do %>
…
<% end %>
I would like like to pass an extra parameter along with the form params:
example: 1
I've tried passing a hash into the path helper, but the params are ignored:
form_tag(example_path(example: 1), method: :get)
How can I add this param without using a hidden field.
In order to what you want to accomplish, you need to update your route:
# config/routes.rb
get "example/:your_param" => "your_controller#example", :as => :example
And then, you will be able to do this in your view:
<%= form_tag (example_path('value'), method: :get) do %>
....
I hope this makes sense and help you.

rails 4 update user profile by button

hy, i'm trying to update a single field in a user resouce. The field to update is 'locale', it is a string type.
i have triend with a form and it works:
<%= form_for current_user do |f| %>
<%= f.select :locale, [['En', 'en'], ['It', 'it']] %>
<%= f.submit %>
<% end %>
now i'm trying to update the same field using a link or a button:
<%= current_user.locale = 'fr' %>
<%= button_to "update" ,current_user,method: :patch %>
<%= button_to "update" ,user_path(current_user),method: :patch %>
but none of this work.
the problem is the request, infact the web server doesn't recive the current_user parameters:
{"_method"=>"patch",
"authenticity_token"=>"7X6QdD4DGxsXaETT86/8Ut4xyuOICaxirs4IjmZl7jY=",
"locale"=>"en",
"id"=>"1"}
There is no current_users parameters.
i have tried with the link_to but the problem is the same:
<%= link_to "update", current_user ,method: :patch %>
I have no idea. Can you help me?
The fact that you don't get the parameter sent back to server is the expected one since you don't use a form.
In order to pass the parameter back you have to:
use a form (as you did) or
pass the parameter in the url of the button: button_to 'update', user_path(param_name: 'param_value')
In the second case, you will have to search for the appropriate parameter in your action, ex params[:param_name]

Resources