Best Practice for views to nested resources in Rails?
I have a fairly simple model; Users have_many products. I would like to be able to view a list of all products as well as a list of the products associated with a given user. My routes are set up like this:
/products
/products/:id
/users
/users/:id
/users/:id/products
The catch here is that I'd like to display the product list differently in the product#index view and the user/products#index view.
Is there a 'correct' way to do this? My current solution is to define products as a nested resource inside users, and then to check for params[:user_id] - if its found I render a template called 'index_from_user', otherwise I just render the typical 'index' template.
This is a situation I'm running into a lot - if there's a preferred way to do 开发者_如何学Pythonit I'd love to know...
You can declare two "products" routes - one under users, and one independent of users eg:
map.resources :products map.resources :users, :has_many => :products
They will both look for "ProductsController#index" but the second will have the "user_id" pre-populated from the route (note: "user_id" not just "id")
So you can test for that in the index method, and display different items depending on whether it is present.
You will need to add a before_filter to the ProductController to actually instantiate the user model before you can use it eg:
before_filter :get_user # put any exceptions here
def index
@products = @user.present? ? @user.products : Product.all
end
# all the other actions here...
# somewhere near the bottom...
private
def get_user
@user = User.find(params[:user_id])
end
If you really want to display completely different views, you can just do it explicitly in the index action eg:
def index
@products = @user.present? ? @user.products : Product.all
if @user.present?
return render(:action => :user_view) # or whatever...
end
# will render the default template...
end
精彩评论