How to route multiple levels of nested resources in Rails 3? - ruby-on-rails

I know I can specify nested resources on routes.rb in Rails 3 this way:
resources :users do
resources :posts
end
However, I would like to add comments to posts. What should I write in my routes.rb file? Is this the correct way? Can I keep nesting them?
resources :users do
resources :posts do
resources :comments
end
end

You can keep nesting the way you have shown and things will work fine. There are quite a few sources that will tell you not to go crazy nesting routes though. Take a look at Rails Best Practices for example (I think the article was created for rails 2 but the principals still apply). Jamis Buck also blogged about this a while ago.

Yes, you can keep nesting and nesting and nesting and so forth.

Yes. What you wrote is the correct way.

I've been interested in this same problem and I think you're suppose to do:
resources :users do
resources :posts
end
resources :posts do
resources :comments
end
Check out the API on Resources.

Related

Rails Engine can share Routes, but not Routing Concerns

I'm trying to share routing concerns of my engine with the host application.
What I'd like to achieve is the following:
# MyGem/config/routes.rb
Rails.application.routes.draw do
concern :commentable do
resources :comments
end
end
# HostApp/config/routes.rb
Rails.application.routes.draw do
resources :posts, concerns: :commentable
end
Which results in No concern named commentable was found!.
I've tested just using the resource without the concern, and I can tell that the host is inheriting my routes, just not concerns.
This could be a load order issue, if the engine routes are loaded last. Which would explain why I could still see the resources comments.
The only thing I can think of is a building a method similar to devise_for :model.
Something along the lines of mygem_concerns, I suppose.
If anyone has any other suggestions I would truly appreciate the help.

Shortening Rails Routes

How might I be able to shorten these extremely lengthy routes in my rails application?
# routes.rb
resources :courses do
resources :sections do
resources :lessons do
resources :sub_lessons
end
end
end
I recommend to follow the rails oficial guides. It is considered a good practice to avoid nesting resources more than 1 level deep. That said, if you really need this level of nesting you can use the shallow option. this way at least your routes will be cleaner. As noted in the documentation cited above:
One way to avoid deep nesting (as recommended above) is to generate the collection actions scoped under the parent, so as to get a sense of the hierarchy, but to not nest the member actions. In other words, to only build routes with the minimal amount of information to uniquely identify the resource
You could try something like this:
resources :courses, shallow: true do
resources :sections, shallow: true do
resources :lessons, shallow: true do
resources :sub_lessons
end
end
end
Just play around with this a little and use rake routes to see how your routes are looking like.
However, what you should ask yourself is, for example do I need to have lessons routed under sections? May be its better to split them, something like:
resources :courses do
resources :sections
end
resources :lessons do
resources :sub_lessons
end
It all depends on the scope you need in what action, for example if at certain action you need to limit lessons based on courses but not in sections, then you will only need the course id passed as a parameter.

Rails "/blog" path uninitialized constant Blog

I am trying to setup a rails blog at the "website.com/blog" url
I already have my models and controller setup to work to where going to
website.com/posts
Gives me all my posts and going to
website.com/posts/1/
Shows me that post, etc, etc. What I want to happen is that when I go to
website.com/blog/
I should see the posts index (and the original URL should no longer work). Similarly I want to go to
website.com/blog/posts/1/
To see that post and so on and so forth.
Right now this is my routes file:
Rails.application.routes.draw do
namespace :blog do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"
end
When I go to "/blog/" I get a Routing Error saying "uninitialized constant Blog". Do I need to create a blog model and controller and migrate to complete this? I'd rather not since it's really just running the posts requests from that new URL. Am I going about this the wrong way?
I ended up finding the answer to my own question here: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
Using this seems to work just fine:
scope '/blog' do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"
The answer ended up being found here: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
As usual the solution was incredibly simple and made me feel like an idiot for not knowing what to do immediately:
scope '/blog' do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"

How can code duplication be avoided in Rails routes?

I have many resources in routes.rb where many few resources are used and repeated.
Is there a way to avoid code duplication?
resources :pages do
resources :comments
##other routes
member { post :vote }
end
resources :videos do
resources :comments
##other routes
member { post :vote }
end
resources :images do
resources :comments
##other routes
member { post :vote }
end
You can organize your routes file so as to keep it from becoming a massive, unmanageable mess. But, it's not via Concerns ... it's actually more "basic" than that. Just break up the files and include them in the main routes file :).
I read a good post on this a while back: splitting routes,rb into smaller parts
Hope it helps.
I've used procs for this myself. Then I just call it in each namespace or resource block where I need it.
But concerns are likely a better and more readable solution.

Rails 3 route scope, exclude one action?

I have my routes set up as
scope "/admin" do
resources :profiles
end
So I am getting the expected routes with /admin/profiles. I want to exclude the show action from having this prefix. Is there an easy way to do this? Every solution I saw in the docs was around nested resources, I'm sure I overlooked something though. Thanks!
I think
scope "/admin", do
resources :profiles, except: :show
end
is what you need.
see more at http://guides.rubyonrails.org/routing.html#restricting-the-routes-created

Resources