Rails Way 处理多条路线上可用的操作
我有以下路线:
resources :users do
# List reviews made by user
resources :reviews, :only => [ :index ]
end
resources :products do
# List reviews by product, and provide :product_id for creation
resources :reviews, :only => [ :index, :new, :create ]
end
# Other actions don't depend on other resources
resources :reviews, :except => [ :index, :new, :create ]
一切看起来都正确,除了ReviewsController#index:
def index
if params[:user_id]
@reviews = Review.find_all_by_user_id params[:user_id]
else
@reviews = Review.find_all_by_product_id params[:product_id]
end
respond_with @reviews
end
我想知道是否有上述问题的标准解决方案,或者是否有更好的方法。
I have the following routes:
resources :users do
# List reviews made by user
resources :reviews, :only => [ :index ]
end
resources :products do
# List reviews by product, and provide :product_id for creation
resources :reviews, :only => [ :index, :new, :create ]
end
# Other actions don't depend on other resources
resources :reviews, :except => [ :index, :new, :create ]
Everything looks right, except ReviewsController#index
:
def index
if params[:user_id]
@reviews = Review.find_all_by_user_id params[:user_id]
else
@reviews = Review.find_all_by_product_id params[:product_id]
end
respond_with @reviews
end
I was wondering if there's a standard solution to the problem above, or if there is a better way to do it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你所拥有的很好,但如果你愿意,你也可以使用两种不同的操作。这种方法应该允许您稍后更轻松地更改视图,并且更安全一些。
它还将使您的控制器代码更加简洁,并且不易受到诸如
/products/10/reviews?user_id=100
之类的奇怪查询的影响,这会导致显示用户的评论而不是产品的评论。另一种选择是也使用不同的控制器:
What you have there is fine, but if you want you can use two different actions as well. This approach should allow you to more easily change the view later on, and is a bit safer.
It will also keep your controller code a little cleaner and less susceptible to odd queries like
/products/10/reviews?user_id=100
which would result in the user's reviews being shown instead of the product's reviews.The other alternative is to use different controllers as well:
有些插件有办法为你加载资源,例如 declarative_authorization 或 cancan,我确信还有其他插件。
我见过的其他解决方案是在控制器中创建一个私有方法来加载对象,并且该方法中的逻辑本质上与您此处的逻辑相同;它只是将其移出索引操作本身。该方法也可以称为前置过滤器。
另一种执行逻辑的方法是从父对象开始(如果您也需要父对象,那就太好了:
Some plugins have ways to load resources for you, such as declarative_authorization or cancan, I'm sure there are others.
Other solutions I have seen is to make a private method in the controller to load the object, and in that method is essentially the same logic you have here; it just moves it out of the index action itself. The metod can also then be called as a before filter.
One other way to do your logic is to start with the parent object (nice if you need the parent object too: