I am following railscast 198 http://railscasts.com/episodes/198-edit-multiple-individually, trying to update it to rails 3, and am stuck with a routing error. The route http://localhost:3000/orders/edit_individual gives me the error:
ActiveRecord::RecordNotFound in OrdersController#show - Couldn't find Order with ID=edit_individual
I have updated and used his rails 2 routing
map.resources :products, :collection => { :edit_individual => :post, :update_individual => :put }
to the rails 3 convention as described by engineyard http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/ (updated to my needs)
resources :orders do
collection do
post :edit_individual
put :update_individual
end
end
Here's what I've tried:
I've tried changing the routes resources as suggested by the answer to: Adding an action to an existing controller (Ruby on Rails) but the same error still shows. I've tried removing the cancan load and authorize resources, the 'resources :orders' route entry, as well as the 'show' entry in the controller, but another error indicates it's still trying to show a record with ID='edit_individual' instead of treating "edit_individual" like a route.
Here are my routes and controller,
myapp::Application.routes.draw do
resources :products
resources :roles
devise_for :users #, :controllers => { :registrations => "registrations" }
# match 'dashboard' => 'user_dashboard#index', :as => 'user_root'
resources :orders do
collection do
post :edit_individual
put :update_individual
end
end
resources :orders
class OrdersController < ApplicationController
load_and_authorize_resource # cancan method
def index
end
def show
end
def edit_individual #from railscast 198
#orders = current_user.customer_orders
end
def update_individual
#orders = Order.update(params[:orders].keys, params[:orders].values).reject { |p| p.errors.empty? }
if #orders.empty?
flash[:notice] = "Orders updated"
redirect_to orders_url
else
render :action => "edit_individual"
end
end # ...etc.
I've removed the cancan methods, but is it the culprit still? I've tried everything I can think of and am at a dead end.. any ideas?
edit:
the output from command prompt:
Started GET "/orders/edit_individual" for 127.0.0.1 at Thu Jun 30 11:19:02 -0700
2011
Processing by OrdersController#show as HTML
Parameters: {"id"=>"edit_individual"}
←[1m←[36mOrder Load (0.0ms)←[0m ←[1mSELECT "orders".* FROM "orders" WHERE "or
ders"."id" = 0 LIMIT 1←[0m
Completed in 2584ms
ActiveRecord::RecordNotFound (Couldn't find Order with ID=edit_individual):
and the route in my html:
<%= link_to 'Update Payments Received', edit_individual_orders_path %>
and rake routes:
edit_individual_orders POST /orders/edit_individual(.:format) {:action=>"edit_individual", :controller=>"orders"}
update_individual_orders PUT /orders/update_individual(.:format) {:action=>"update_individual", :controller=>"orders"}
orders GET /orders(.:format) {:action=>"index", :controller=>"orders"}
POST /orders(.:format) {:action=>"create", :controller=>"orders"}
new_order GET /orders/new(.:format) {:action=>"new", :controller=>"orders"}
edit_order GET /orders/:id/edit(.:format) {:action=>"edit", :controller=>"orders"}
order GET /orders/:id(.:format) {:action=>"show", :controller=>"orders"}
PUT /orders/:id(.:format) {:action=>"update", :controller=>"orders"}
DELETE /orders/:id(.:format) {:action=>"destroy", :controller=>"orders"}
You should probably run "rake routes" and see what route it gives for "edit_individual" action.
Also your log
Started GET "/orders/edit_individual" for 127.0.0.1 at Thu Jun 30 11:19:02 -0700
says that you are calling a post action as get.
Try below
resources :orders do
collection do
get :edit_individual
put :update_individual
end
end
OR either way you can use
<%= link_to 'Update Payments Received', edit_individual_orders_path, :method => "post" %>
So the error message: OrdersController#show - Couldn't find Order with ID=edit_individual tells me that for whatever reason you're being routed to the 'show' action, which is inherently expecting something like
/orders/1
meaning it's a member not a collection. Are you certain that the url being hit in your server output matches /orders/edit_individual?
Related
I'm taking an MOOC and the goal of this exercise is to add a new functionality to typo, where i can merge two articles together.
When I add the route to my new function merge to the routes.rb I'm losing the functionality to delete articles. I think something clashes here, but I have no idea what.
The original routes.rb:
%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
This method in articles.rb creates the correct url for deleting
def delete_url
blog.url_for(:controller => "/admin/content", :action =>"destroy",:id => id)
end
correct url:
http://example.com/admin/content/destroy/7
If i follow this link i can successfully delete an article.
However, if I add the following before that to my routes.rb:
namespace "admin" do
resources :content do
post :merge, on: :member, as: :merge
end
end
The new merging functionality and forms are working fine, but the method delete_url now produces something like this:
http://example.com/admin/content/7
and if I follow a link created by this method i get:
Unknown action
The action 'show' could not be found for Admin::ContentController
Maybe I'm overwriting something? I can't figure out what's happening here and why this affects the delete action / route.
Thanks in advance!
EDIT: rake routes | grep content:
with the original routes.rb gives me:
admin_content /admin/content {:controller=>"admin/content", :action=>"index"}
/admin/content(/:action(/:id)) {:action=>nil, :id=>nil, :controller=>"admin/content"}
whereas my modified routes.rb produces
merge_admin_content POST /admin/content/:id/merge(.:format) {:action=>"merge", :controller=>"admin/content"}
admin_content_index GET /admin/content(.:format) {:action=>"index", :controller=>"admin/content"}
POST /admin/content(.:format) {:action=>"create", :controller=>"admin/content"}
new_admin_content GET /admin/content/new(.:format) {:action=>"new", :controller=>"admin/content"}
edit_admin_content GET /admin/content/:id/edit(.:format) {:action=>"edit", :controller=>"admin/content"}
admin_content GET /admin/content/:id(.:format) {:action=>"show", :controller=>"admin/content"}
PUT /admin/content/:id(.:format) {:action=>"update", :controller=>"admin/content"}
DELETE /admin/content/:id(.:format) {:action=>"destroy", :controller=>"admin/content"}
/admin/content {:controller=>"admin/content", :action=>"index"}
/admin/content(/:action(/:id)) {:action=>nil, :id=>nil, :controller=>"admin/content"}
Okay, thanks to #guitarman i worked through my routes code and found out I can add the following except:
namespace "admin" do
resources :content, except: [:index, :show, :update, :destroy, :edit, :new, :create] do
post :merge, on: :member, as: :merge
end
end
after that, the rake routes just shows the additional merge route I wanted and my destroy action works fine again.
Check rake routes command. I think there is a route /admin/content/:id which will be created by resources :content in the namespace "admin".
Your request to http://example.com/admin/content/7 will be catched be the defined route but I gess you have no show action in the controller.
Better:
namespace "admin" do
post "/content/:id/merge", to: "admin/content#merge", as: :merge
end
For more information about recources and the CRUD operations please see the rails routing guide.
Strangely when I include "resources :blogs" to my routes.rb I get the following error for any other path I try to reach:
No route matches {:action=>"show", :controller=>"blogs"}
The only path I don't get this error for is the "/blogs/:id(.:format)" itself.
Rake routes ("show" for "blogs" in line 5):
blogs GET /blogs(.:format) blogs#index
POST /blogs(.:format) blogs#create
new_blog GET /blogs/new(.:format) blogs#new
edit_blog GET /blogs/:id/edit(.:format) blogs#edit
blog GET /blogs/:id(.:format) blogs#show
PUT /blogs/:id(.:format) blogs#update
DELETE /blogs/:id(.:format) blogs#destroy
root / pages#home
home /home(.:format) pages#home
products /products(.:format) pages#products
services /services(.:format) pages#services
research /research(.:format) pages#research
/blog(.:format) pages#blog
contact /contact(.:format) pages#contact
On the other hand when tried in console there is no such error for "/products" (for instance) which in the browser returns the "No route matches" error:
1.9.3p327 :010 > Rails.application.routes.recognize_path "/products"
=> {:controller=>"pages", :action=>"products"}
1.9.3p327 :011 > Rails.application.routes.recognize_path "/blogs/1"
=> {:action=>"show", :controller=>"blogs", :id=>"1"}
Any idea?
UPDATE:
Here is my blogs_controller.rb:
class BlogsController < ApplicationController
def show
#blog = Blog.find(params[:id])
end
def new
end
end
and my show.html.erb of the blogs:
<%= #blog.title %>, <%= #blog.description %>
So far this is all I have developed to test my Blog model.
Most likely, you have something like
<%= link_to "Blogs", blog_path =>
in layout template. If so, correct it to <%= link_to "Blogs", blogs_path =>
I've got Rails routing problem. I would like to use singular resource with user controller but it doesn't work as I expected. Here is the fragment of my routes.rb file:
scope :module => "frontend" do
root :to => "home#index"
resource :user, :controller => "user"
get "/sign_up" => "user#new"
get "/sign_in" => "user#sign_in"
get "/sign_out" => "user#sign_out"
post "/authenticate" => "user#authenticate"
resources :articles
resources :article_categories
end
I thought it will work when I'll use for example "/user" or "/user/new" URL but it didn't. I get a routing error:
No route matches {:controller=>"frontend/user"}
The 'rake routes' command output is:
user POST /user(.:format) frontend/user#create
new_user GET /user/new(.:format) frontend/user#new
edit_user GET /user/edit(.:format) frontend/user#edit
GET /user(.:format) frontend/user#show
PUT /user(.:format) frontend/user#update
DELETE /user(.:format) frontend/user#destroy
sign_up GET /sign_up(.:format) frontend/user#new
sign_in GET /sign_in(.:format) frontend/user#sign_in
sign_out GET /sign_out(.:format) frontend/user#sign_out
authenticate POST /authenticate(.:format) frontend/user#authenticate
What is interesting, when I add route for index action in user controller, like this:
scope :module => "frontend" do
root :to => "home#index"
resource :user, :controller => "user"
get "/user" => "user#index"
get "/sign_up" => "user#new"
get "/sign_in" => "user#sign_in"
get "/sign_out" => "user#sign_out"
post "/authenticate" => "user#authenticate"
resources :articles
resources :article_categories
end
...it works!
But index action is not defined in user controller!
'rake routes' command returns double line for GET /user
GET /user(.:format) frontend/user#show
GET /user(.:format) frontend/user#index
so I suppose that's not the solution. Other actions assigned to '/users' URL don't work.
Is it necessary to define the route for the index action like
get "/controller_name" => "controller_name#index"
What am I doing wrong?
Defining a singular resource in your routes will not generate a route to an index action by design. The singular resource implies you're always going to lookup this resource without specifying an ID and consequently a get to index for a singular resource just doesn't make logical sense. So, a GET to your url "/user" will route to a show action for that singular resource and not an index.
EDIT: Since your issue isn't obvious, I'd simplify your routes until you can at least hit the controller you'd expect and then build from there.
config/routes.rb
scope :module=>"frontend" do
resource :user
end
#ensure you don't have any other user routes listed before this that would match "/user".
app/controllers/frontend/users_controller.rb
module Frontend
class UsersController < ApplicationController
def show
raise "in frontend/show"
end
end
end
Thanks a lot for help! I found the bug.
The routing error was caused by the following line of the layout html file
<%= auto_discovery_link_tag(:rss, {:action => "index"}, {:title => "RSS"}) %>
I was looking for errors in the erb view files but I forgot about the layout.
I must remember to check the entire view layer in such situations.
I am trying to create tests for nested resources in Rails. The relevant route definition is:
resources :communities do
resources :contents, :type => 'Content'
end
Using RSpec and factory_girl, I am trying to get started with testing with e.g.
describe ContentsController do
it 'should display a content item under a community' do
content = FactoryGirl.create(:content)
get :show, :community_id => content.community.id, :id => content.id
end
end
These requests always result in
Failure/Error: get :show, :community_id => content.community.id, :id => content.id
ActionController::RoutingError:
No route matches {:community_id=>BSON::ObjectId('4e7773c6ac54c3d1ad000002'),
:id=>BSON::ObjectId('4e7773c6ac54c3d1ad000001'), :controller=>"contents",
:action=>"show"}
For the life of me I cannot find a way to specify a route to a nested resource with RSpec. Am I doing something fundamentally wrong here?
Update: The relevant part of rake routes is:
community_contents GET /communities/:community_id/contents(.:format) {:action=>"index", :controller=>"contents"}
POST /communities/:community_id/contents(.:format) {:action=>"create", :controller=>"contents"}
new_community_content GET /communities/:community_id/contents/new(.:format) {:action=>"new", :controller=>"contents"}
edit_community_content GET /communities/:community_id/contents/:id/edit(.:format) {:action=>"edit", :controller=>"contents"}
community_content GET /communities/:community_id/contents/:id(.:format) {:action=>"show", :controller=>"contents"}
PUT /communities/:community_id/contents/:id(.:format) {:action=>"update", :controller=>"contents"}
DELETE /communities/:community_id/contents/:id(.:format) {:action=>"destroy", :controller=>"contents"}
I see that you are passing the content.community.id as the :community_id and that object looks like a mongo document that is identified with a BSON::ObjectId. Try to use to_param instead as following:
get :show, :community_id => content.community.to_param, :id => content.to_param
I have a has_one relation:
# supplier.rb
has_one :presentation
...
# presentation.rb
belongs_to :supplier
...
and the folowing nested routes for them:
# routes.rb
resources :suppliers do
resource :presentation
end
running rake routesgives:
supplier_presentation POST ... {:action=>"create", :controller=>"presentations"}
new_supplier_presentation GET ... {:action=>"new", :controller=>"presentations"}
edit_supplier_presentation GET ... {:action=>"edit", :controller=>"presentations"}
GET ... {:action=>"show", :controller=>"presentations"}
PUT ... {:action=>"update", :controller=>"presentations"}
DELETE ... {:action=>"destroy", :controller=>"presentations"}
Why no name_helper for the show action?
I can override the problem doing something like:
resources :suppliers do
resource :presentation, :except => :show do
get "" => "presentations#show", as: "presentation"
end
end
giving the route:
presentation_supplier_presentation GET ... {:controller=>"presentations", :action=>"show"}
but we all now that's not the right way to deal with it..
ANY SUGGESTIONS?
--
(edited)
supplier_presentation_path(#supplier)
does work, but why?... It doesn't appear when rake routes is executed on my shell...
I dont really know why it's not displayed when you do rake routes but did you try in your code to do supplier_presentation_path(#supplier)? It should work based on your routes.
Never the less it should work for you. Try this:
link_to "Presentation", [#suplier, #presentation]
or
link_to "Presentation", suplier_presentation_path(#suplier, #presentation)