form_with model altering url parameters for edit form - ruby-on-rails

The REST route for EDIT is overriding the first URL parameter in addition to the last URL parameter but other parameters are unaltered.
How do I stop the form from changing the url first parameter?
views/rounds/edit.html.erb
<h1>Editing Round</h1>
<%= render 'form', round: #round %>
<%= link_to 'Show', round_path(params[:tid],params[:rid]) , class: 'btn btn-primary' %> |
<%= link_to 'Back', tournament_path(params[:tid]), class: 'btn btn-primary' %>
views/rounds/_form.html.erb
<%= form_with(model: round, local: true) do |form| %>
...
<div class="actions">
<%= form.submit ( form.object.new_record? ? "Create" : "Update"), class: 'btn btn-primary'%>
</div>
<% end %>
config/routes.rb
get "tournaments/:tid/rounds" => "rounds#index", as: 'rounds'
get "tournaments/:tid/rounds/new" => "rounds#new", as: 'new_round'
post "tournaments/:tid/rounds" => "rounds#create"
delete "tournaments/:tid/rounds/:rid" => "rounds#destroy"
patch "tournaments/:tid/rounds/:rid" => "rounds#update"
put "tournaments/:tid/rounds/:rid" => "rounds#update"
get "tournaments/:tid/rounds/:rid" => "rounds#show", as: 'round'
get "tournaments/:tid/rounds/:rid/edit" => "rounds#edit", as: 'edit_round'
get "tournaments/:tid/rounds/:rid/matches/:mid/points" => "points#index", as: 'points'
get "tournaments/:tid/rounds/:rid/matches/:mid/points/new" => "points#new", as: 'new_point'
post "tournaments/:tid/rounds/:rid/matches/:mid/points" => "points#create"
delete "tournaments/:tid/rounds/:rid/matches/:mid/points/:pid" => "points#destroy"
patch "tournaments/:tid/rounds/:rid/matches/:mid/points/:pid" => "points#update"
put "tournaments/:tid/rounds/:rid/matches/:mid/points/:pid" => "points#update"
get "tournaments/:tid/rounds/:rid/matches/:mid/points/:pid" => "points#show", as: 'point'
get "tournaments/:tid/rounds/:rid/matches/:mid/points/:pid/edit" => "points#edit", as: 'edit_point'
http://localhost:3000/tournaments/1/rounds/2/edit
page form has action:
<form action="/tournaments/2/rounds/2" accept-charset="UTF-8" method="post">
why is :tid being updated to :rid and how do i prevent it.
http://localhost:3000/tournaments/1/rounds/2/matches/3/points/10/edit
has the same problem with :tid being updated to match :pid but all other params are intact.
<form action="/tournaments/10/rounds/2/matches/3/points/10" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓">
How do i ensure the edit page routes do not change the :tid parameter in the URL

Remove all the routes to tournaments, rounds, matches and points and use resources routes
resources :tournaments do
resources :rounds do
resources :matches do
resources :points
end
end
end
Then check if it works.

Related

creating a form to route a method inside controller

I am trying to create a form that redirects to a method called accept_item on the form controller. My issue is that it's not going through the accept_item method when I submit the form.
form_controller.rb
def accept
#form = Form.find(params['id'])
end
def accept_item
redirect_to inventories_path
end
accept.html.erb
<%= form_tag accept_item_forms_url do %>
<% #form.items.each do |i| %>
<%= label_tag 'Item Name' %>
<p><%= i.name %></p>
<%= label_tag 'Quantity' %>
<p><%= text_field_tag 'quantity', i.quantity %></p>
<% end %>
<%= submit_tag 'Accept', class: 'btn btn-default btn-about pull-left', data: {confirm: 'Are you sure you want to accept?'} %>
<% end %>
routes.rb
resources :forms do
collection do
get :accept_item, :as => :accept_item
end
end
Error Message
No route matches [POST] "/forms/accept_item"
The form_tag helper uses the HTTP POST method by default. You defined your routes with get:
get :accept_item, :as => :accept_item
You should use post instead:
post :accept_item, :as => :accept_item
Also I don't think you need the as: :accept_item part, unless you're going to use accept_item_url instead of accept_item_forms_url.
just remove :as => :accept_item, and change method to post
post :accept_item
You will get /foo when using :as => 'foo'.

Rails - Silmple Form calls a specified action of my user controller

My problem is that when i try to call a specified method from a simple_form_for form it doesn't work.
Here is my code :
<%= simple_form_for #user, :url => {:action => :register_iban}, :html => { :method => :post } do |f| %>
<div class="col-md-8">
<%= f.input :first_name, :label => t('user-show.payment.form.first_name'), placeholder: "Prénom" %>
<%= f.input :last_name, :label => t('user-show.payment.form.last_name'), placeholder: "Nom" %>
<%= f.input :iban, :label => t('user-show.payment.form.iban'), placeholder: "IBAN" %>
<%= f.input :bic, :label => t('user-show.payment.form.bic'), placeholder: "BIC" %>
</div>
<div class="col-md-8 text-center">
<%= f.submit t('user-show.payment.title'), class: 'btn btn-danger' %>
</div>
<% end %>
So, as you can see, i try to call register_iban method from my user controller.
But when i do that, i have an error : No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
Everytime i create a new method in a controller, i have to create a route in the routes.rb file ? Here, i'd like to make this url : /users/5/register_iban (where "5" is the user id) call my method.
Sorry but i start in ruby and i'm pretty stuck :/
in your config/routes.rb try to add in the users resources
resources users do
member do
post :register_iban
end
end
No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
This error means you're trying to access a route which doesn't exist.
The routes are defined at config/routes.rb:
#config/routes.rb
resources :users do
post :register_iban
end
This will allow you to call the register_iban method in the users controller through your form.
You'll also want to make sure you're calling routes with the appropriate helpers:
<%= simple_form_for #user, url: user_register_iban(#user) %>

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.

How do you update a nested has_one resource?

I seem to have two problems
1) While trying to update my singular nested resource
Restaurant has_one Hour
and
Hour belongs_to Restaurant
resources :restaurants do
resource :hour
end
with an edit link on my restaurant show page called:
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
and the edit page has a partial render that looks like:
<%= render :partial => 'restaurants/hours', :locals => { :hour => 'hour' } %>
which loads a partial named _hours.html.erb:
<%= form_for hour do |f| %>
<div class="row-fluid">
<div class="span1 hours_input">
<h3>Monday</h1>
From
<%= f.text_field :from_monday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_monday, :class => 'span20 hour_field' %>
</div>
<div class="span1 hours_input">
<h3>Tuesday</h3>
From
<%= f.text_field :from_tuesday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_tuesday, :class => 'span20 hour_field' %>
</div>
<div class="span1">
<%= f.submit 'Set Hours' %>
</div>
</div>
but once I press the submit button it gives me the error:
No route matches [POST] "/restaurants/34/hour/edit"
I tried setting it as:
<%= form_for hour, :method => put, :html => { :action => 'update' } do |f| %>
but with no luck.
Any help would be greatly appreciated!
I'm using rails 3.2.3
2) My second problem is rather mysterious.
Once I press on the button
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
on the restaurant show page, it'll give the url:
http://localhost:3000/restaurants/34//hour/edit
with the double slash before //hour. I suspect this will break in production but doesn't seem to affect me in development.
Again, thanks for reading and have a good one!
Edit: Here's the rake routes--
restaurant_hour POST /restaurants/:restaurant_id/hour(.:format) hours#create
new_restaurant_hour GET /restaurants/:restaurant_id/hour/new(.:format) hours#new
edit_restaurant_hour GET /restaurants/:restaurant_id/hour/edit(.:format) hours#edit
GET /restaurants/:restaurant_id/hour(.:format) hours#show
PUT /restaurants/:restaurant_id/hour(.:format) hours#update
DELETE /restaurants/:restaurant_id/hour(.:format) hours#destroy
restaurants GET /restaurants(.:format) restaurants#index
POST /restaurants(.:format) restaurants#create
new_restaurant GET /restaurants/new(.:format) restaurants#new
edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
restaurant GET /restaurants/:id(.:format) restaurants#show
PUT /restaurants/:id(.:format) restaurants#update
DELETE /restaurants/:id(.:format) restaurants#destroy
hour GET /:restaurant/hour(.:format) hours#show
POST /:restaurant/hour(.:format) hours#create
hour_add GET /:restaurant/hour/add(.:format) hours#new
hour_edit GET /:restaurant/hour/edit(.:format) hours#edit
I figured it out, but it's apparently not the RESTful way to do it.
I just had to add:
<%= form_for hour, :url => { :action => "update" }, :html => { :method => 'put' } do |f| %>
and specify the action/method for the update to work.
Another post suggested that just using:
<%= form_for #hour do |f| %>
would have worked, too, but I wasn't having any luck with that for some reason.

rails admin edit view path routes

I've got an admin section setup, but am having trouble getting the "update" route to work.
Getting error when hitting "update" via the edit view:
"No action responded to 2."
For some reason the route is responding to the :id as the :action.
Parameters:
Parameters: {"commit"=>"Update", "action"=>"2", "_method"=>"put", "admin"=>{"ended_at(1i)"=>"2010", "ended_at(2i)"=>"8", "ended_at(3i)"=>"22"}, "id"=>"edit", "controller"=>"admin/subscriptions"}
The edit view uri:
/admin/subscriptions/2/edit
Edit view:
<% form_for :admin, #subscription, :html => {:method => :put} do |f| %>
<p>
<%= f.label :ended_at %><br />
<%= f.date_select :ended_at %>
</p>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
Route:
map.namespace :admin do |admin|
admin.resources :subscriptions
end
I assume I need to do something differently in the form_for method or maybe the routes, but everything I've tried isn't working.
Thanks for the help!!
It should be this:
<% form_for [:admin, #subscription] do |f| %>
By putting :admin and #subscription in square-brackets, this makes it into an array which is passed as the first argument to form_for. The benefit of this is if #subscription is a pre-existing record (as-in, one found by find, not created with new) then Rails will know to set the form method to PUT.
This works:
<% form_for :admin, #subscription, :html => {:method => :put}, :url => { :action => "update" } do |f| %>
Seems verbose though. Any better ideas?
Try
- form_for :subscription, #subscription do |f|
We're using formtastic here.

Resources