I have the following models:
And I have the following routes.rb
file:
resources :tags resources :posts do resources :tags end
So when I navigate to, say, /posts/4/tags
, that will shoot me into the index action for the Tag controller with the post_id
value set in the parameters array. Cool.
My question is though, now that I'm accessing the nested tags resource under posts, should I be hitting the Tags controller still? Or should I setup some other controller to handle the nested nature of tags at this point? Otherwise I have to build additional logic into the Tags controller. This can be done of course, but is this the common way of handling nested routes and resources? The code I have in the index action for the Tags controller is as follows:
TagsController.rb
def index if params[:post_id] && @post = Post.find_by_id(params[:post_id]) @tags = Post.find_by_id(params[:post_id]).tags else @tags = Tag.order(:name) end respond_to do |format| format.html format.json {render json: @tags.tokens(params[:q]) } end end
I can see the code in this controller growing increasingly large, as I plan for many additional resources to be associated with tag resources. Thoughts on how to break this out?
Summary of questions:
Let me know if you need more information.
In Rails, there are seven standard CRUD actions: index, show, new, create, edit, update, and destroy, which relate to specific HTTP verbs and are usually implemented using specific ActiveRecord methods.
Difference between singular resource and resources in Rails routes. So far, we have been using resources to declare a resource. Rails also lets us declare a singular version of it using resource. Rails recommends us to use singular resource when we do not have an identifier.
In a nested route, the belongs_to (child) association is always nested under the has_many (parent) association. The first step is to add the nested routes like so: In the above Rails router example, the 'index' and 'show' routes are the only nested routes listed (additional or other resources can be added).
Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. A single call to resources can declare all of the necessary routes for your index , show , new , edit , create , update , and destroy actions.
I think the best solution is to split up controllers:
resources :tags resources :posts do resources :tags, controller: 'post_tags' end
And then you have 3 controllers. Optionally, you can inherit PostTagsController from TagsController to do something like:
class PostTagsController < TagsController def index @tags = Post.find(params[:post_id]).tags super end end
If the difference is only the retrieval of tags, you can:
class TagsController < ApplicationController def tags Tag.all end def tag tags.find params[:id] end def index @tags = tags # ... end # ... end class PostTagsController < TagsController def tags Product.find(params[:product_id]).tags end end
Use that methods and simply override tags in the inheriting controllers ;)
All you are doing with nested resources is changing the routing URL. Only thing you would have to do is make sure you are passing the proper id (in your case post)to the tag controller. Most common error is the Can't Find *** ID.
If you don't nest a profile route into a user route it would look like this
domain.com/user/1
domain.com/profile/2
When you nest the routes it would be
domain.com/user/1/profile/2
That is all that it is doing and nothing else. You don't need additional controllers. Doing nested routing is just for looks. allowing your user to follow the association. The most important thing about nesting routes is that you make sure you make the link_to's to the right path.
When not nested: it would be
user_path
and
profile_path
when it is nested you would need to use
user_profile_path
rake routes
is your friend to find out how the routes have changed.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With