Rails处理多个路径上可用的操作的方法

Mat*_*ira 5 ruby design-patterns ruby-on-rails ruby-on-rails-3

我有以下路线:

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 ]
Run Code Online (Sandbox Code Playgroud)

一切看起来都是正确的,除了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
Run Code Online (Sandbox Code Playgroud)

我想知道是否有上述问题的标准解决方案,或者是否有更好的方法来做到这一点.

Pan*_*kos 6

你有什么是好的,但如果你想要你也可以使用两种不同的行动.这种方法应该可以让您以后更轻松地更改视图,并且更安全一些.

match '/products/:product_id/reviews' => 'reviews#product_index'
match '/users/:user_id/reviews' => 'reviews#user_index'
Run Code Online (Sandbox Code Playgroud)

它还可以使您的控制器代码更加清晰,并且不易受到奇怪的查询的影响,/products/10/reviews?user_id=100这会导致显示用户的评论而不是产品的评论.

def product_index
  @reviews = Review.find_all_by_product_id params[:product_id]
  respond_with @reviews
end

def user_index
  @reviews = Review.find_all_by_user_id params[:user_id]
  respond_with @reviews
end
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用不同的控制器:

match '/products/:product_id/reviews' => 'product_reviews#index'
match '/users/:user_id/reviews' => 'user_reviews#index'
Run Code Online (Sandbox Code Playgroud)