这可能是向您的 : 添加新的资源丰富的成员路由实际上是合理的少数情况之一QuestionsController
:
resources :questions do
post 'answer', :on => :member
end
它将question/:id/answer
通过路由到的 POST 请求进行识别questions#answer
,从而允许您将所有逻辑保存在一个控制器中:
class QuestionsController < ApplicationController
...
def show
@question = Question.find(params[:id])
end
def answer
@question = Question.find(params[:id])
@answer = @question.answers.build(params[:question][:answer])
if @answer.save
# show question with newly posted answer at url /question/:id
redirect_to @question
else
# show question with invalid editable answer at url /question/:id/answer
render 'show'
end
end
...
end
说明:在我看来,在一个控制器而不是两个控制器中处理逻辑的决定归结为您认为感兴趣的资源。通常,您会认为每个模型代表一个不同的资源,因此创建一个单独的控制器来处理与每个资源相关的操作。然而,当有多个深度耦合的模型在单个视图中处理多个动作(例如show
, )时new
,将模型视为形成单个资源可能更清晰。create
在这个例子中,我认为资源是一个由问题和答案组成的集体资源。由于这个集体资源是由问题本身唯一标识的,我会让问题控制器处理它。问题控制器中的show
动作已经涉及检索集体问答资源,因此您可能会将answer
动作(以及潜在unanswer
的reanswer
动作)视为该update
集体资源的类似物。
以这种方式考虑资源很大程度上取决于设计偏好,并且会根据需求进行权衡。