Rails 3: named parameter routes break link_to - ruby-on-rails-3

I'm trying to create a Rails app that divides the users by groups and sub-groups and offers a customized site to each sub-group. I figured the easiest way to do that was to create scope with named parameters:
scope ":group/:subgroup/" do
devise_for :users
resources :users
end
"rake routes" then produces this:
users GET /:group/:subgroup/users(.:format) {:action=>"index", :controller=>"users"}
POST /:group/:subgroup/users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /:group/:subgroup/users/new(.:format) {:action=>"new", :controller=>"users"}
edit_user GET /:group/:subgroup/users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /:group/:subgroup/users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /:group/:subgroup/users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /:group/:subgroup/users/:id(.:format) {:action=>"destroy", :controller=>"users"}
It works perfectly--except when I to use link_to:
link_to current_user.name, current_user
Then it throws this error
ActionController::RoutingError in Users#index
Showing C:/Rails/MyApp/app/views/users/_my_list.html.haml where line #8 raised:
No route matches {:action=>"show", :controller=>"users", :group=>#<User id: 7, email: "username#domain.com", encrypted_password: "$2a$10$GdZeC0b4VaNxdsDXP...", password_salt: "$2a$sj$88gm0nttYE.7a4IHi.BNO", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 86, current_sign_in_at: "2011-08-05 17:18:19", last_sign_in_at: "2011-08-05 00:14:26", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", confirmation_token: nil, confirmed_at: "2010-12-09 23:08:54", confirmation_sent_at: "2010-12-09 23:08:36", failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2010-12-09 23:08:36", updated_at: "2011-08-05 17:18:19", name: "UserOne">}
Line #8, of course, is where I tried to use link_to. My guess is that link_to is ignoring the scope, which accounts for current_user getting stuffed into the :group parameter. Is there a way to keep this from happening, or am I going about this whole issue totally wrong?

Your resource :users is inside the scope, so you don't have the /users/:id route.
You could try this:
scope ":group/:subgroup/" do
devise_for :users
end
resources :users
I'm not sure if the scope has a shallow => true option (I think it does and you should probably use it).
Hope that helps

The problem is you can't reach an user without passing in a group and a subgroup. Reading your error it's possible to understand that rails is trying to convert your current_user to the group.

Related

no route matches controller (Rails 3)

I'm pretty new to RoR, please help me identify where I am wrong
I get the following error
Routing Error
No route matches {:controller=>"groups"}
Try running rake routes for more information on available routes
when trying to render the following view
<li><%= link_to 'My groups', user_groups_path %></li>
<li><%= link_to 'New group', new_user_group_path %></li>
and here is 'routes.rb' and rake routes output
devise_for :users
resources :users do |user|
resources :groups do |group|
resources :people do |person|
end
end
end
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session GET /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
user_group_people GET /users/:user_id/groups/:group_id/people(.:format) people#index
POST /users/:user_id/groups/:group_id/people(.:format) people#create
new_user_group_person GET /users/:user_id/groups/:group_id/people/new(.:format) people#new
edit_user_group_person GET /users/:user_id/groups/:group_id/people/:id/edit(.:format) people#edit
user_group_person GET /users/:user_id/groups/:group_id/people/:id(.:format) people#show
PUT /users/:user_id/groups/:group_id/people/:id(.:format) people#update
DELETE /users/:user_id/groups/:group_id/people/:id(.:format) people#destroy
groups GET /users/:user_id/groups(.:format) groups#index
POST /users/:user_id/groups(.:format) groups#create
new_user_group GET /users/:user_id/groups/new(.:format) groups#new
edit_user_group GET /users/:user_id/groups/:id/edit(.:format) groups#edit
user_group GET /users/:user_id/groups/:id(.:format) groups#show
PUT /users/:user_id/groups/:id(.:format) groups#update
DELETE /users/:user_id/groups/:id(.:format) groups#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
here is 'model.rb'
class User < ActiveRecord::Base
has_many :groups
class Group < ActiveRecord::Base
belongs_to :user
has_many :people
please help me figure out how to fix the problem
many thanks.
UPD
here is solution, it works
I made all changes suggested by #Abibullah and two changes in controllers
view:
<li><%= link_to 'My groups', user_groups_path(current_user) %></li>
<li><%= link_to 'New group', new_user_group_path(current_user) %></li>
routes.rb
resources :users do |user|
resources :groups do |group|
resources :people
end
end
devise_for :users
GroupsController.rb:
def index
#user = current_user
#user.groups = Group.all
was:
def index
#user = current_user
#groups = Group.all
end
UsersController.rb
class Devise::UsersController < DeviseController
def show
end
end
To Create a nested Group Inside User, U need to pass the user_id inside which U are Creating the Group.
For Ex: If I have user1
Then I will use the routes as this:
link_to 'My groups', user_groups_path(user1)
OR
link_to 'My groups', user_groups_path(user1.id)
AND
link_to 'My Group', new_user_group_path(user1)
OR
link_to 'My Group', new_user_group_path(user1.id)
This is to tell that, To which User you are creating the Group.
If U want to access any specific Group, say for ex: grp1
then My url will be
link_to 'My Group', user_group_path(user1, grp1)
THis is a good refrence for routing.
http://guides.rubyonrails.org/routing.html
I think it's obvious. You've got a typo in your
<li><%= link_to 'My groups', user_groups_path %></li>
link. The path should be user_group_path (without the 's') as shown in your rake routes output, instead of the one you've written in your link.

Custom Rails 3 routes

Suppose I have an events controller. If I request /events by GET it will respond with index action in news controller, this view will display future events.
I want to add a new action called past, it is like index, which return an array of Events but with another query.
I have added to routes.rb this chunk:
resources :events do
collection do
get :past
end
end
and I this chuck to events_controller:
def history
#events => Event.past
render :template => 'index'
end
But when I request http://127.0.0.1:3000/events/past in browser it does not work, in log are thrown these lines:
Started GET "/events/past" for 127.0.0.1 at 2012-04-02 19:32:01 -0500
Processing by EventsController#show as HTML
Parameters: {"id"=>"past"}
And finally here you have rake routes output:
events GET /events(.:format) {:action=>"index", :controller=>"events"}
event GET /events/:id(.:format) {:action=>"show", :controller=>"events"}
past_events GET /events/past(.:format) {:action=>"past", :controller=>"events"}
contact_us_event POST /events/:id/contact_us(.:format) {:action=>"contact_us", :controller=>"events"}
GET /events(.:format) {:action=>"index", :controller=>"events"}
POST /events(.:format) {:action=>"create", :controller=>"events"}
new_event GET /events/new(.:format) {:action=>"new", :controller=>"events"}
edit_event GET /events/:id/edit(.:format) {:action=>"edit", :controller=>"events"}
GET /events/:id(.:format) {:action=>"show", :controller=>"events"}
PUT /events/:id(.:format) {:action=>"update", :controller=>"events"}
DELETE /events/:id(.:format) {:action=>"destroy", :controller=>"events"}
Other test was check routes using Rails console:
$ script/rails c
1.9.2-p318 :001 > rs = ActionController::Routing::Routes
1.9.2-p318 :002 > rs.recognize_path "/events/past", :method => :get
=> {:action=>"show", :controller=>"events", :id=>"past"}
What's wrong?
The problem was on routes precedence, here you have a routes.rb chunk that works:
resources :events, :only => [:index, :show] do
get 'past', :on => :collection
post 'contact_us', :on => :member
end
Try:
resources :events do
get :past, :to => "events#past"
end
I don't think you need the collection context. (And you might not need the :to part)
Update
Another way to do it is to put the event call above the resource. Assuming you don't need the collection with it.
get 'events/past', :to => "events#past"
resources :events
Should provide you with the correct routes.
For reference: Rails 3 routes: How to avoid conflict with 'show' action?

Rails 3 routing error with namespace and uncountable noun together

Well this is my first time doing this. In routes.rb I have the following:
namespace :admin do
resources :news
end
And I have this after rake routes:
admin_news_index GET /admin/news(.:format) admin/news#index
POST /admin/news(.:format) admin/news#create
new_admin_news GET /admin/news/new(.:format) admin/news#new
edit_admin_news GET /admin/news/:id/edit(.:format) admin/news#edit
admin_news GET /admin/news/:id(.:format) admin/news#show
PUT /admin/news/:id(.:format) admin/news#update
DELETE /admin/news/:id(.:format) admin/news#destroy
As you can see the path to the action "new" is new_admin_news_path, unfortunately, when I visited that path, something pop up as follow:
No route matches {:action=>"show", :controller=>"admin/news", :id=>#<News id: nil, news_type_id: nil, title: nil, content: nil, views: nil, status: nil, start_date: nil, end_date: nil, created_at: nil, updated_at: nil, news_key: nil>}
I was thinking that the "news" is an uncountable noun and this might be the problem. So I change the config/initializers/inflections.rb to:
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable %w( fish sheep news )
end
Obviously, it is not working...
What should I do? Any suggestions?

BEGINNER: simple link_to / routing

I'm really starting to cry here ;) Trying to make a link in a Models index view.
I have 2 simple Models: Users and Posts. There both generated with scaffolding and have working joins. A user has_many :posts and a post belongs_to :user.
What I'm trying to do in the views/post/index.html.er file is a list of the Post title and the user who it belongs to. It works well (also learning html5):
<% #posts.each do |post| %>
<p><%= link_to post.user.name, users_path %>: <b><%= post.title %></b></p>
<% end %>
Well, it works but the "users_path" is not what I want. I want to link to the specific User which the post belongs_to. I'm sorry to say that I don't get much help from http://guides.rubyonrails.org/routing.html.
How should I do this? Do I have to specify a #user in the posts_controller index-action? I reallt appreciate long and detaild answears here.
Tnk soooo much for patience with a beginner ;)
you probably have this in your routes -
resources :posts do
resources :users
end
rake routes would generate the following mapping -
post_users GET /posts/:post_id/users(.:format) {:action=>"index", :controller=>"users"}
POST /posts/:post_id/users(.:format) {:action=>"create", :controller=>"users"}
new_post_user GET /posts/:post_id/users/new(.:format) {:action=>"new", :controller=>"users"}
edit_post_user GET /posts/:post_id/users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
post_user GET /posts/:post_id/users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /posts/:post_id/users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /posts/:post_id/users/:id(.:format) {:action=>"destroy", :controller=>"users"}
posts GET /posts(.:format) {:action=>"index", :controller=>"posts"}
POST /posts(.:format) {:action=>"create", :controller=>"posts"}
new_post GET /posts/new(.:format) {:action=>"new", :controller=>"posts"}
edit_post GET /posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
post GET /posts/:id(.:format) {:action=>"show", :controller=>"posts"}
PUT /posts/:id(.:format) {:action=>"update", :controller=>"posts"}
DELETE /posts/:id(.:format) {:action=>"destroy", :controller=>"posts"}
The above explains the url you can use and what objects need to be passed.
For linking the user of the post -
<%= link_to "Post User details", post_user_path(post, post.user) %>
OR
<%= link_to "Post User details", url_for([post, post.user]) %>

Rails RoutingError: No route matches {:controller=>"sessions", :action=>"destroy"}

Yet when run rake:routes it appears to be there:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}
sessions POST /sessions(.:format) {:action=>"create", :controller=>"sessions"}
new_session GET /sessions/new(.:format) {:action=>"new", :controller=>"sessions"}
session DELETE /sessions/:id(.:format) {:action=>"destroy", :controller=>"sessions"}
signup /signup(.:format) {:controller=>"users", :action=>"new"}
contact /contact(.:format) {:controller=>"pages", :action=>"contact"}
about /about(.:format) {:controller=>"pages", :action=>"about"}
help /help(.:format) {:controller=>"pages", :action=>"help"}
root /(.:format) {:controller=>"pages", :action=>"home"}
Here are the routes from routes.rb:
resources :users
resources :sessions, :only => [:new, :create, :destroy]
match '/signup', to: 'users#new'
match '/contact', to: 'pages#contact'
match '/about', to: 'pages#about'
match '/help', to: 'pages#help'
It's possible that you are not passing the :id param in your route, which is why the route is not matched, since :id is required:
session DELETE /sessions/:id(.:format) {:action=>"destroy", :controller=>"sessions"}
Note: The parentheses around the :format param mean that it is optional.
I got the same error as well.But the reason is the little mistake that in the view page I write
<%= form_for(:session,url:session_path) do |f| %>
which I less the last 's' of 'sessions'.
This looks like an error I was running into when running through http://ruby.railstutorial.org/, and it turned out that I had left a few things out of routes.rb. The addition of the resource route is accompanied by the following two additional routes:
match '/signin', :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy'
It's hard to see because the first route in that group is already there, so I had just glossed over the group (several times) as already being there.
resources controller adds map to method
{:action=>"method", :controller=>"controller"}
when in your case the rails seemed to ask for explicitly the map as
{:controller=>“controller”, :action=>“method”}
The :controller is before :action
This also answered Noach's question why match '/signout', :to => 'sessions#destroy' has to exist, if you rake:routes you will see it added
{:controller=>“sessions”, :action=>“destroy”} while there is already a
{:action=>“destroy”, :controller=>“sessions”} added by resources sessions