How do I update create route from rails 3 to 4 - ruby-on-rails

I have a form tag which is seen below, when I try to run the page I get the error: No route matches {:action=>"create", :type=>"new", :controller=>"lists"}
<%= form_for #list, :url => {:action => "create", :type => "new"}, :html => {:multipart => true,:role=>"form"} do |f| %>
In my routes file i have a line-- resources :lists
I thought the line above in the routes file is supposed to create correct routes for me.
Can someone tell me what I am doing wrong?

The url option needs a controller if you're going to format things this way... and there isn't a type option in url_for... so it should probably look like this:
<%= form_for #list, :url => {:controller => 'lists', :action => "create"}, :html => {:multipart => true,:role=>"form"} do |f| %>
Or without the hash rockets:
<%= form_for #list, url: { controller: 'lists', action: "create" }, html: { multipart: true, role: "form"} do |f| %>

check the method, create must be sent via POST as
<%= form_for #list, as: :list :url => lists_path, method: :post do |f| %>

Related

RoR differences between :url, :action, :method in form_for

There might be answers in documentation, but i don't seem to find good answers.
So among the three :url, :action, :method, what are their differences when used in form_for in Rails?
Difference between :url, :action and :method
:url
If you want to submit your form for any particular controller, any particular action and want to pass some extra parameter (use action that define in controller that you pass on controller )
for example
<%= form_for #post, :url => {:controller => "your-controller-name", :action => "your-action-name"} do |f| %>
In the above code the form is submitted to that controller(that you pass on url) and goto that (you pass on action) action. it will take defaults to the current action.
now suppose you want to pass extra parameter then for example
form_for #post, :url => { :action => :update, :type => #type, :this => #currently_editing } do |f| ...
you can pass extra parameter like :type => #type
so :url is The URL the form is submitted to. It takes the same fields you pass to url_for or link_to. In particular you may pass here a named route directly as well.
:action
form_for #post, :url => { :action => :update, :type => #type, :this => #currently_editing } do |f| ...
In the above example we pass :action if we want to submit the form in different action then we pass :action and your-action-name the form is post to that action
:method
method is used for which method you want to pass for that action. There are several methods like put,post,get ...
for example
form_for #post, :url => post_path(#post), :method => :put, ....
In the above form_for we pass :method => :put when this form is submit it will use put method
form_for is basically used on object. For example:
<% form_for #person do |f| %>
...
<% end %>
When you click submit it will go to default action like from :new to :create, :edit => :update. If you want to specify your own action then you have to use :url and :method is used to force to post or get. For example:
<% form_for #person :url => {:action => "my_action"}, :method => "post" do |f| %>
...
<% end %>
URL:
Url is the path where your form data should go.
whatever you write inside the :url symbol is considered as the path where your data should go when u click a submit button in the form.
Action:
Action is the method in your controller, in your form_for #user (where #user is a object of User model), if you say :action => create then it sumbit the data to users_controller 'create' function (def create).
You will mention this inside :url to tell that the data should go to the specifiled action.
Method:
Is http method, there are 'get', 'post', 'update', 'patch' and 'delete' method. You can learn about this in google.

POST from a form to a custom action not being processed by the action - Routing error instead

I have a search form that needs to POST to 'users/search'. Following are the relevant code snippets:-
Form
<%=simple_form_for #user, :url => search_user_path(#user), :input_html => {:method => :post} do |f|%>
<div id="top" style="width:979px; height:30px;">
<%= select "search", :area_id, Area.find(:all).collect { |p| [p.name, p.id]}, {:selected => current_user.address.area} %>
<%= f.association :categories, :as => :check_boxes, :label => false%>
<%= f.submit "Submit"%>
</div>
<% end %>
I expect this to POST to users/:id/search
routes.rb
resources :users do
member do
post 'search'
end
end
rake routes | grep search
search_user POST /users/:id/search(.:format) {:action=>"search", :controller=>"users"}
So the route exists
Users controller has the following method
def search
Rails.logger.debug('In users#search')
end
When I hit submit I get a Routing error
Started POST "/users/9/search" for 127.0.0.1 at 2011-10-28 14:11:04 +0530
ActionController::RoutingError (No route matches "/users/9/search"):
I am clueless on this and after a lot of wasted research I am resorting to the community for inputs. Any pointers will be hugely appreciated. Thanks.
FYI I am on rails 3.0.9 and ruby 1.9.2
-Tarun
You need to write this in plural:
search_users_path(#user)
Also your form is a little bit weired. You could simply write
<%= form_for #user, search_users_path(#user) do |f| %>
Instead of
<%=simple_form_for #user, :url => search_user_path(#user), :input_html => {:method => :post} do |f|%>
You dont need the :method => :post

Additional Parameter in form_for in Rails

Is it possible to submit another parameter outside the form data in rails? My problem is that I render different forms for different classes and send them to the same create method. I would like to send the class with the form (as value not as key in the hash).
Something like the :type parameter (that actually doesn't work)
<%= form_for(#an_object, :url => { :controller => :a_controller, :action => :create },
:type => #an_object.class.to_s.underscore) do |f| %>
The post message looks like:
{"commit"=>"Create Class of an Object",
"authenticity_token"=>"/iqu0A8/AocDT3HyjL5/+bKZiLkyr4FE71u/mc8Wx0Y=",
"utf8"=>"✓",
"class_of_an_object"=>{"name"=>"a name",
"description"=>"a description"}}
and I would have a "type" => "class_of_an_object", but directly in the hash an not within the "class_of_an_object" hash.
<%= form_for #an_object,
:url => { :controller => :a_controller,
:action => :create,
:type => #an_object.class.to_s.underscore } do |f| %>
And I prefer to use named routes
<%= form_for #object, :url => object_path(#object, :type => "whtever"), :html => {:method => :post} do |f| %>
This works for me:
<%= form_for #foo, :url => foo_path(:type => "whatever"), :html => {:method => :post} do |f| %>

Rails 3 Rspec form_for Deprecation Warning

I have a form_for in my application which looks like:
<%= form_for :user, #user, :url => { :controller => 'users', :action => 'update' }, :html => { :multipart => true, :method => 'put' } do |f| %>
This works fine. However, when I run my tests with Rspec I always get:
DEPRECATION WARNING: Using form_for(:name, #resource) is deprecated. Please use form_for(#resource, :as => :name) instead.
Which seems to go against what is written in the Rails 3 forms guide. Is this just a bug in rspec or is it actually a deprecation?
You should just be able to do this
<%= form_for #user, :html => {:multipart => true} %>
Since Rails will know that #user is an existing record, it'll know to do a PUT request to users_controller#update.

Rails: Passing multiple parameters to form_for url?

This works great:
- form_for #user, :url => { :action => :create, :type => #type } do |f| ...
Returns /users/(id)?type=type
But in another view I need to pass TWO parameters into the URL string, and this does not work:
- form_for #user, :url => { :action => :update, :type => #type, :this => #currently_editing } do |f| ...
Returns /users/(id)?this=currently_editing
I've also tried:
- form_for #user, :url => { :action => :update, :params = params.merge({:this => #currently_editing, :type = #type})} do |f| ...
... with no luck (error: only GET requests allowed).
What I want is for it to return this: /users/(id)?this=currently_editing&type=type
Thoughts?
Why do you need to pass them into the URL string? Why not just add them as hidden fields in the form? In almost all cases you should pass the variables that way with POSTs.
I would use hidden fields, but this should work:
<% form_for #user, :url => user_path(#user.id, :type => #type, :this => #currently_editing), :method => :put do |f| -%>
:method => :put triggers the update action when using RESTful routes.
please try to this
you can pass more than one parameter in this way.
- form_for #user, :url => xxx_yyy_path(:param1 => value1, :params2 => value2, ......) do |f| ...
I think you have to move the desired querystring attributes outside of the :url option like this:
form_for #user, :url => { :action => :update }, :type => #type, :this => #currently_editing do |f|

Resources