我的应用有照片模型。这些照片可以属于一些其他类,例如,主题,用户,标签。我希望能够根据不同的相关ID查询所有照片。我已经设置了嵌套资源,如:
resources :topics do
resources :photos, only: ['index']
end
...
resources :users do
resources :photos, only: ['index']
end
我想知道在控制器中处理这个问题的最佳做法是什么。 我最初的反应是写一个if / else块,但这感觉非常不重要。
if !params[:user_id].nil?
# query based on user id
elsif !params[:topic_id].nil?
# query based on topic id
etc.
我还讨论了设置控制器操作和路由到那些,例如user_photos#photos,topic_photos#photos。
或者设置一些新的控制器:UserPhotosController,TopicPhotosController
这些都不是正确的,我想知道是否有人有一些见解,或者是否有一个共同的设计模式来处理这样的事情。
这是一个Rails 4项目,顺便说一句。
答案 0 :(得分:1)
如果您可以在一个控制器类中组合控制器逻辑,那么您应该这样做。我不明白为什么基于param值的选择应该是un-ruby。这似乎是正确的做法。
答案 1 :(得分:1)
你可以使用if语句。
你可以做的另一件事是你的if语句,然后把你的参数放到哈希中。然后,您可以将此哈希值传递给模型查找,以便在特定主题下查看特定用户的照片。
这方面的例子是这里的答案: https://stackoverflow.com/a/4480139/2589358
我发现这是一个很好的方法,因为它更容易管理,以后添加更多的params,而且它看起来更干净。
答案 2 :(得分:1)
首先,在Rails 4中,您可以使用concerns
:
concern :imageable do
resources :photos, only: ['index']
end
resources :topics, concerns: :imageable
resources :users, concerns: :imageable
现在,我看到了解决这种情况的两种方法。
选项A :将if-else移动到只获得可成像的方法,即用户,标签,主题等。在您的PhotosController中:
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
def index
respond_with photos
end
private
def photos
@photos ||= imageable ? imageable.photos : Photo.all
end
# Find and cache the imageable based on the id in params.
# Using find instead of find_by_id. This is to ensure ActiveRecord::RecordNotFound
# exception in the case of an invalid id passed, which be handled with render_404 method
def imageable
@imageable ||= begin
if id = params[:user_id]
User.find(id)
elsif id = params[:topic_id]
Topic.find(id)
end
end
end
def render_404
respond_to do |format|
format.html { render template: 'errors/not_found', layout: 'layouts/application', status: 404 }
format.all { render nothing: true, status: 404 }
end
end
选项B :改变您的路线:
resources :photos, only: ['index'] do
resources :topics
resources :users
end
然后相应地更改TopicsController
,UsersController
等,然后您无需创建UserPhotosController
,TopicPhotosController
等。