Simple Rails 3 Route is Failing - No route matches - ruby-on-rails-3

In my config/routes.rb I have:
post "portal_plan_document/update"
rake routes confirms this:
$ rake routes
portal_plan_document_update POST /portal_plan_document/update(.:format) {:controller=>"portal_plan_document", :action=>"update"}
....
In my code I have:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:method => "POST", :remote => true do |f| %>
In my log file I see:
Started POST "/portal_plan_document/update" for 127.0.0.1 at 2011-03-31 18:04:37 -0400
ActionController::RoutingError (No route matches "/portal_plan_document/update"):
I am lost as what to do from here. Any help would be greatly appreciated!
I should state I am using Ruby 1.9.2 and Rails 3.0.5. Oh, I have restarted the server (WebBrick w/rails server) after updating routes.rb.
Jeremy

Figured it out! :)
if you have a non-empty object, rails assumes you want to update that object. i.e., use a 'PUT' instead of a 'POST'
to accomplish 'PUTs', rails will put a hidden input in the form, with "_method" = "put". so, it LOOKS like it's a POST, but rails is treating it as a PUT.
if you actually want to just update an object (what it looks like you're doing), a PUT is better, and you should just switch your routes over to PUT.
if (like I was), you're doing something that really requires a POST (i.e., it can't be sent more than once safely), you can write your form_for like this:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:html=>{:method => "POST"}, :remote => true do |f| %>
to confirm, look at the generated HTML source, and make sure the hidden "_method" field is not set to "put"

Try using that instead please :
:method => :post
If this does not still work, please lose the remote attribute and give it a try. Does it work without it ?

I had the same problem while upgrading a simple app from Rails 2 to Rails 3.
As you may guess I was updating all "remote_form_for(#item) (..)" helpers to "form_for :item remote => true (..)" syntax.
In my case this code from a items/_new.html.erb partial:
<%= form_for :item, :remote => true do |f| %>
<!--FIELDS-->
<% end %>
Gave me this error:
Started POST "/items/new" for 127.0.0.1 at Fri Aug 12 18:19:23
+0200 2011
ActionController::RoutingError (No route matches "/items/new")
As you can notice the method was a correct "POST", not a "PUT". The problem lied in the routing... I don't know why but when a remote POST method is sent by a partial, Rails routes the POST request to "/items/new" instead of "/items" route. Even if the purpose is to create a new "item" so the POST request should be correctly (and RESTfully) routed to "/items".
This code, with explicit action and controller, solved the problem:
<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" } do |f| %>
<!--FIELDS-->
<% end %>

Related

Rails: No route matches [PUT] "/blog/2"

I am creating blog application in rails. I have a common form for creating and updating blog.
This is view of edit and new.html.erb
<%= render :partial => "form"%>
This is view of _form.html.erb blog:
<%= form_for #blog do |f| %>
<%= f.text_field :title, :placeholder => "Title" %><br>
<%= f.cktext_area :article, :placeholder => "Content", :ckeditor => {:toolbar => "MyToolbar"} %>
<%= f.submit %>
<% end %>
My blog is creating successfully but I am getting error on update action. This is my edit and update action in blog controller:
def edit
#blog = Blog.find_by_slug(params[:id])
end
def update
#blog = Blog.find(params[:id]) || not_found
#blog.update_attributes(params[:blog])
redirect_to "/blogs/#{#blog.slug}"
end
When I open form from edit view, and click on update button, it throws error:
No route matches [PUT] "/blog/2"
My routes.rb is:
resources :blogs
get 'blog', to: 'blogs#index'
get '/blog/:id', to: 'blogs#show', as: 'blog'
I am not getting where it is going wrong. I tried to add "url: blogs_path" in form_for, it removes the error but doesn't save the edit changes.
Can anybody help me where I am going wrong here?
Thank you.
Okay. I dont understand why you want to go against conventions. Anyway, using form_for resource would automatically generate action URL as a PUT to /resources/:id if its an update operation.
So to override this you need to do two things.
update your routes to support this:
Add this line to your routes file:
put 'blog/:id' => 'blogs#update', :as => 'update_blog'
It is important that you put this line above your 'resources :blogs` call.
2 . specify the URL to which the form should submit:
You will need to create the form tag like this:
<%= form_for #blog, :url => update_blog_path(#blog) do |f| %>
Try this and let us know.

Rails 3 Search Action Redirects To Show?

I've ran into a weird problem in Rails. When I try and submit a search query with the following form on my Uploads controller:
<%= form_tag ({:controller => "uploads", :action => 'find_uploads'}), :method => "get" do %>
<%=h text_field_tag :search, params[:search], :id => 'search_field' %>
<br />
<%= submit_tag "Search", :style=>"display:inline;" %>
<% end %>
I get redirected to the following url and error page:
/uploads/find_uploads?utf8=✓&search=bot&commit=Search
ActiveRecord::RecordNotFound in UploadsController#show
Couldn't find Upload with id=0
My find_uploads route: get 'uploads/find_uploads' => "uploads#find_uploads"
And when I did I rake routes this is what I got:
uploads_find_uploads GET /uploads/find_uploads(.:format) {:controller=>"uploads", :action=>"find_uploads"}
Everything seems to be in order... not sure why it's not working out as expected. For debugging purposes I dropped breakpoints in both my find_uploads and show actions and neither of them were reached so this error message must be lying to me as the UploadsController show action is never called!
This form is being rendered on my index page if it counts for anything.
I think it's taking find_uploads for an id.
Declare your routes like that:
resources :uploads do
collection do
get :find_uploads
end
end
ps: currently, when you do rake routes, /uploads/find_uploads is after /uploads/:id right?

url_for adding controller and action to querystring in rails 3.2

I am trying to generate a url in an actionmailer template. An example if the url I want to generate is
http://0.0.0.0:3000/users/confirm/lNbQxzFukYtEEw2RMCA
Where the last segment is a hash to identify the user
However when I use this
<%= url_for(:controller => 'users', :action => 'confirm', :id => #user.confirmhash, :only_path => false) %>
It generates this
http://0.0.0.0:3000/assets?action=confirm&controller=users&id=ZOR3dNMls8533T8hJUfCJw
How can I get it to correctly format? I have no idea where 'assets' is coming from.
Is there an easier way to use named routes that I am missing?
I've found the answer. As I'm still learning I've missed the option to create a named route. So this this the path I've taken.
In config/routes.rb
match 'user/confirm/:id' => 'users#confirm', :as => :confirm_account
Then in my action mailer template I've used
<%= link_to "Confirm your account", confirm_account_url(#user.confirmhash) %>
Which passes the :id into the controller action.

Rails3 form_tag routing error

I'm having trouble getting a view and controller to play nice together. I think I messed up my routing, any help would be great.
My controller looks like:
class AccountDetailsController < ApplicationController
def new
puts "in new"
end
def home
puts "in home"
end
end
My routes.rb looks like:
resources :account_details
My new.html.erb looks like:
<h1>AccountDetails#new</h1>
<%= form_tag(url_for(:controller => "account_details", :action => "new"), :method => "post") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Submit") %>
<% end %>
when I goto http://localhost:3000/account_details/new
I get my page and when I hit submit, I get this error:
Started POST "/account_details/new" for 0:0:0:0:0:0:0:1%0 at Wed May 02 22:38:10 -0400 2012
ActionController::RoutingError (No route matches [POST] "/account_details/new"):
Other than being clueless, what am I doing wrong? I thought my route would cover the [POST], no?
The proper method for creating new entry is PUT, not POST. You should remove :method => "post" from your template, so PUT method will be chosen automatically.

Rails 3 nested resource route problem as form_for

I have nested resources like this in my routes.rb - (my rake:routes gist)
namespace(:admin) do
resources :restaurants do
resources :menus
resources :menu_items
end
end
In the controller:
def new
#restaurant = Restaurant.find(params[:restaurant_id])
#menu_item = #restaurant.menu_items.build
end
Trying to create a new MenuItem (action #new), by the url: http://127.0.0.1:3001/admin/restaurants/1/menu_items/new I get the error:
NoMethodError in Admin/menu_items#new
Showing /home/fps/workspace3/peded/app/views/admin/menu_items/_form.html.erb where line #1 raised:
undefined method `admin_menu_items_path' for #<#<Class:0xb6582d78>:0xb6581f2c>
Extracted source (around line #1):
1: <%= form_for #menu_item do |f| %>
...
How do I make this form work? It was created out of a nifty:scaffold
UPDATE
I also tried this in the _form:
<%= form_for [:restaurant, #menu_item] do |f| %>
But ended with a similar error:
Showing /home/fps/workspace3/peded/app/views/admin/menu_items/_form.html.erb where line #1 raised:
undefined method `restaurant_admin_menu_items_path' for #<#<Class:0xb68162b0>:0xb6813dd0>
Extracted source (around line #1):
1: <%= form_for [:restaurant, #menu_item] do |f| %
Should I file a bug?
form_for([#restaurant, #menu_item])
I think the problem is in the form. This worked for me:
<%= form_for(#menu_items, :url => restaurant_menu_items_path(#menu_items.restaurant)) do |f| %>
I'm having the same issue. The only solution I have found is to pass a url to the form_for.
<% url = (action_name == "new" ? {:action=>"create", :controller=>"admin/menu_item"} : {:action=>"update", :controller=>"admin/menu_item"})%>
<%= form_for [#restaurant ,#menu_item], :url=>url do |f| %>
One additional note, you will not get params[:menu_item] back, instead you will see params[:admin_menu_item].
Hope that helps you out!
You can look up your routes by running on the command line.
rake routes
It looks like you're calling your routes incorrectly.
Array notation would be:
form_for([:admin, #restaurant, #menu_item])
And the named route for create:
admin_restaurant_menu_items_path(#restaurant)
Dealing with nested resources and namespaces is a Vietnam (pita).
Here is my nasty solution:
= form_for #admin_menu_item,
:url => (#admin_menu_item.try(:new_record?) ?
admin_restaurant_menu_items_path(#admin_restaurant) :
admin_menu_item_path(# admin_menu_item)) do |f|
...
I hope you can help.
The only solution that worked for me correctly (for both new and edit resource) was:
form_for #menu_item, :url => url_for([:admin, #restaurant, #menu_item])
I'm using Rails 5 (not that I imagine it matters) and this worked for me:
= simple_form_for [:admin, #restaurant, #menu_item] do |f|
The fact that it's simple_form_for rather than form_for probably doesn't matter either.
Funnily enough, I'm building an app with the same exact resource names.