Do not post a form in a Rails root route - ruby-on-rails

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.

Related

form_with model altering url parameters for edit form

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.

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) %>

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

Editing a single form field with rails

I have a form field in a view that is separate from my initial form. I want the person using the application to be able to edit a single field without having to pull up the entire form. My code is as follows
<%= form_for :user, :url => {:controller => 'users', :action => 'update' } do |f| %>
<%= f.text_field :barcode %>
<%= submit_tag 'Register' %>
<% end %>
When trying to submit the changes to the specified form field I receive an error on the create method I believe. It redirects me to the user controller with the proper id but gives me the following error.
Unknown action
The action '1' could not be found for UsersController
I have tried changing the method from update to create, but then it brings up the blank form, I just want to be able to edit the specified field without having to re-create the form and get the error. Any ideas?
You are not passing the user object to the form.
Try also using the path helper generated by the routes:
<%= form_for #user, :url => user_path(#user) do |f| %>
<%= form_for(#user), :url => url_for(:controller => 'users', :action => 'update') do |f| %>
<%= f.text_field :barcode %>
<%= f.submit, 'Register' %>
<% end %>
It should work now...

Resources