rails nested resources handle edit path as id - ruby-on-rails

I have the following routes
resources :users, path: '/' do
resources :posts, path: '/'
end
the problem is that the inner route override the outer route for user's edit path.
http://localhost/user/edit refer to posts#show instead users#edit
EDIT
Singular resource is not the solution, I want to access the user via his ID.
lets say I have user with id "Jo" and post with id "My-First-Post", then the corresponding route should be http://localhost/Jo/My-First-Post. that's work just fine with my current solution.
the problem is that when I access /Jo/edit I get exception that there is no post with id "edit" while I want this route to refer to Jo's edit page (users#edit)

What are you trying to achieve? It sort of looks like you want a singular resource. If that's the case, you can just do:
routes.rb
resource :user
So just make the word resource and user singular. Then you'll get singular routes, like user/edit.
See the Rails guide for more information: http://guides.rubyonrails.org/routing.html#singular-resources

Related

How to remove the prefix generated in routes.rb for the params in the path

Currently in my routes I have:
# USER RESOURCES
resources :users do
resources :repositories
patch 'change_password'
get 'account_setting'
end
Which generates this path for the account_setting action:
user_account_setting GET /users/:user_id/account_setting(.:format) users#account_setting
What I want is to have:
user_account_setting GET /users/:id/account_setting(.:format) users#account_setting
The two are essentially the same thing, but the first has a user_ prefix for the id which rails adds because it is in users resource block.
SIDE NOTE
I know I can simply remove the account_setting action from the users resource block and write:
get 'users/:id/account_setting', to: 'users#account_setting'
But I don't want to.
You can do it as follows:
resources :users do
member do
get 'account_setting'
end
end
To add a member route, add a member block into the resource block.
For documentation, you can check http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html

Rails Routing Error 'no route matches'

I'm getting this routing error on my site. I've went through other related questions and haven't found a solution yet.
No route matches {:action=>"show", :controller=>"businesses", :user_id=>3}
I have three models: user (contains login details), business (contains info related to users: one user has_one business), and business_hours (one business has many business_hours).
Here are my routes:
devise_for :users
get "home/index"
root :to => "home#index"
resources :users do
resources :businesses do
resources :business_hours
end
end
Edit:
I get the error just trying to access the home page (localhost:5000). I'm currently signed in. I have run rake routes and the route seems to be there:
user_business GET /users/:user_id/businesses/:id(.:format) businesses#show
the routes which you have mentioned is expecting a forth argument which is the id of the businesses,try to pass the id of businesses it will work
user_business GET /users/:user_id/businesses/:id(.:format)
ideally you need to use this for index
user_businesses GET /users/:user_id/businesses(.:format)
your question is not so clear otherwise i could have given a precise answer hope this helps

Ruby on Rails : add a new route

I'm new with RoR so this is a newbie question:
if I have a controller users_controller.rb and I add a method foo, shouldn't it create this route?
http://www.localhost:3000/users/foo
because when I did that, I got this error:
Couldn't find User with id=foo
I of course added a view foo.html.erb
EDIT:
I added to routes.rb this code but I get the same error:
resources :users do
get "signup"
end
This doesn't work automatically in rails 3. You'll need to add
resource :users do
get "foo"
end
to your routes.rb
You'll definitely want to have a look at http://guides.rubyonrails.org/routing.html, it explains routing pretty well.
Rails is directing you to the show controller and thinks that you're providing foo as :id param to the show action.
You need to set a route that will be dispatched prior to being matched as /users/:id in users#show
You can accomplish this by modifying config/routes.rb by adding the following to replace your existing resource describing :users
resource :users do
get "foo"
end
Just to add to the other answers, in earlier versions of Rails there used to be a default route
match ':controller(/:action(/:id))(.:format)'
which gave the behaviour you describe where a request of the form controller/action would call the given method on the given controller. This line is still in routes.rb but is commented out by default. You can uncomment it to enable this behaviour but the comment above it explains why this is not recommended:
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
At the schema ':controller/:action(.:format)', you can also easily do the following
resources :users do
get "foo", on: :collection
end
or
resources :users do
collection do
get 'foo'
end
end
http://guides.rubyonrails.org/routing.html#adding-collection-routes

route works one place, not others

This is kind of difficult to communicate but I'll try without pasting all my code. I have Members who have one Mailbox which has many Receipts. In the header layout I have a nav that calls
<%= link_to "Message Center", member_mailbox_path(current_user.member_id) %>
It works on most pages like trails/# , the resource pages for various models
But on other pages, seems like custom route pages, I get this error
No route matches {:action=>"show", :controller=>"mailbox", :member_id=>16}
Running rake routes shows this:
member_mailbox GET /members/:member_id/mailbox/:id(.:format) mailbox#show
Routes are confusing to me, here are my routes for this problem (show message isn't tested yet) ...
resources :members do
resources :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
The routes for the pages that are showing the error are similar to this one
match '/my_plays', :to => "trails#my_plays"
match '/my_creations', :to => "trails#my_creations"
So not sure if my routes are right. I wonder if resources :mailbox is correct since I don't have a bunch of resources for that, it's a has_one .... THX
----EDIT--- after changing route per advice:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
You may want to define a mailbox as a singular resource in your routes. Otherwise, Rails will expect you to pass in both the user id and the mailbox id for member_mailbox_path to route to mailbox#show. I believe this is why you're getting a routing error. Since each user has one mailbox, there's no need to make this extra lookup part of the route. So instead of resources :mailbox, you can do resource :mailbox:
resources :members do
resource :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
I believe this would generate the following routes:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
Notice that the lack of path names next to GET, PUT, and DELETE doesn't mean they don't exist; they're just repeats of the POST path, but each responds to different HTTP methods.
To render mailboxes#show, you'll need to add a MailboxesController with a show route, which might do a look up for the member:
class MailboxesController < ApplicationController
def show
#member = Member.find(params[:member_id])
# other mailbox code...
end
end
And you'll also create a template at app/views/mailboxes/show.html.erb to render the mailbox show page.
Also, I would recommend against deeply nesting your routes, as in third level :receipts.

newbie: how to get dynamic links for current_user?

Im trying to figure out how to get a dynamic link for example
/users/user1/show
/users/user1/edit
or
/profiles/1/
How would I create a route that I could insert in my views like a view_profile_path and that would include the id or username of a user?
in config/routes.rb you need to add 1 simple line:
resources :users
and get all this stuff
HTTP Verb Path action named helper
GET /users index users_path
GET /users/new new new_user_path
POST /users create users_path
GET /users/:id show user_path(:id)
GET /users/:id/edit edit edit_user_path(:id)
PUT /users/:id update user_path(:id)
DELETE /users/:id destroy user_path(:id)
You can read about rails routes in the guides
Actually, I think you need something like this in config/routes.rb
resources :users do
resources :profiles
end
You can later check your REST-ful resource routes by issuing the command:
rake routes
This way you have a more natural approach to your routes in which your users will be bound to one or more profiles, therefore you may use something like:
user_profile_path(#user)
to create an appropriate link to a user's profile.

Resources