Rails 3 nested resource route problem as form_for - ruby-on-rails-3

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.

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 routes - Resource not appending _path

I am attempting to use resources to auto generate routes for my resource. The namespace is admin and the resource is author. The following code seems to work for most instances.
namespace :admin do
resources :author
end
When I run
rake routes
I get the following
admin_author_index GET /admin/author(.:format) admin/author#index
POST /admin/author(.:format) admin/author#create
new_admin_author GET /admin/author/new(.:format) admin/author#new
edit_admin_author GET /admin/author/:id/edit(.:format) admin/author#edit
admin_author GET /admin/author/:id(.:format) admin/author#show
PUT /admin/author/:id(.:format) admin/author#update
DELETE /admin/author/:id(.:format) admin/author#destroy
From what I can tell I am expecting the named paths to have a
_path
at the end. I am rather green at this. I have searched and searched but I could just be using the wrong terms to find the answer. Any help is appreciated. Thanks!
-edit- I should add that
<%= form_for [:admin, #author] do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit %>
<% end %>
Gives me errors saying it can not find admin_author_path
You can append either _path or _url to these. Basically everything looks good.
So for example
admin_author_index GET /admin/author(.:format) admin/author#index
the helper method can be admin_author_index_path or admin_author_index_url. These helpers can be used in controllers and views to point to a controller/action or url. Read this link http://guides.rubyonrails.org/routing.html to understand more.
No. The route name does not have the _path suffix.
Refer to Rails routing from inside in for more information. It explains routing in great detail.

RoR: form_for action button doesn't respond

I'm coding the project from Ruby on Rails Tutorial: Learn Rails by Example and am having trouble with the following and unfollowing features.
I have a piece of HTML in one of my pages that looks like this:
<%= form_for current_user.relationships.build(:followed_id => #user.id),
:remote => true do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<div class="actions"><%= f.submit "Follow" %></div>
<% end %>
My RelationshipsController has a create method, but it is never called. The same applies to my 'unfollow' html and corresponding destroy method. Is there something I need to add to my project to let Rails know that the relationships.build method should call the create method, or is that automatic?
Thanks in advance.
RelationshipsController has a create method
current_user.relationships.build()
Is it create or build?
Show us the controller code. Since you use "remote=> true" you probably need to change the "respond_to" code in there and create a js.erb file.

Simple Rails 3 Route is Failing - No route matches

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

Rails 3 path for edit and new actions in a basic form view

I have the following routes:
resources :categories do
resources :articles
end
And the following views:
# edit.erb and new.erb files:
<%= render :partial => 'form' %>
# top of _form.html.erb file:
<%= form_for category_article_path(#article.category, #article) do |f| %>
But I have some troubles with the given path. I work with Rails 3. Here is an example of error that I get when testing:
undefined method `category' for
nil:NilClass
What is the basic way to write a such path? Many thanks.
Just pass a freshly newed up article (with an existing category) instance to the view.