0

例如,有一个Question模型has_many :answers

我想在questions#show(就像stackoverflow一样)上显示一个新答案的表格

路线将类似于:

resources :questions do
  resources :answers
end

在这些情况下,显示无效记录错误的最佳方式是什么?

问题是我不能render从内部执行我需要的操作AnswersController(因为它会是questions#show),唯一的方法似乎是redirect_to将错误存储在flash哈希中。

它看起来像一个非常常见的场景,我相信应该有一些更好的方法

4

3 回答 3

2

这可能是向您的 : 添加新的资源丰富的成员路由实际上是合理的少数情况之一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动作(以及潜在unanswerreanswer动作)视为该update集体资源的类似物。

以这种方式考虑资源很大程度上取决于设计偏好,并且会根据需求进行权衡。

于 2012-10-14T06:02:08.440 回答
1

您可以像这样渲染questions#showAnswersController

render :template => 'questions/show'

如果您想跳转到页面上的特定锚点,您必须在您的答案表单中定义它:

<%= form_for(@answer, :url => question_answers_url(@question, :anchor => 'answer_form')) do |f| -%>
于 2012-10-13T15:54:38.303 回答
-1

具有将数据发布到 answers_controller#create 操作的形式的部分。

因此,在您的问题#show 页面 - show.html.erb 中,呈现部分

<%= render :partial => "answers/answer_form" %>

在 _answer_form.html.erb 中,有一个将数据发布到 answers#create 的表单

<% form_for @answer do |f| %>
  # have a text area
<% end %>

就闪光灯而言

在 AsnwersController

def create
  @question = Question.find(params[:question_id])
  @answer = Answer.build(params)
  if @answer.save
    flash[:notice] = "Answer was posted successfully"  
  else
    flash[:error] = "There were a few errors please try again"  
  end
  redirect_to question_path(@question) 
end
于 2012-10-14T06:35:54.813 回答