rails respond_with相关记录

时间:2012-09-30 21:20:29

标签: ruby-on-rails ruby ruby-on-rails-3 grails-controller respond-with

例如,有Question

has_many :answers模型

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

路线可能是这样的:

resources :questions do
  resources :answers
end

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

问题是我无法在render AnswersControllerquestions#show进行redirect_to所需的操作(因为它会是flash),唯一的方法似乎是{{1}}并在{{1}}哈希中存储错误。

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

3 个答案:

答案 0 :(得分:2)

这可能是少数情况之一,它实际上有理由向您的QuestionsController添加新的足智多谋成员路线:

resources :questions do
  post 'answer', :on => :member
end

通过POST请求路由到question/:id/answer来识别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

说明:在我看来,在一个控制器中处理逻辑而不是两个控制器的决定归结为你认为是感兴趣的资源。通常,您会考虑每个模型来表示不同的资源,从而创建一个单独的控制器来处理与每个资源相关的操作。但是,当存在多个深度耦合的模型时,在单个视图中处理多个操作(例如shownewcreate),将模型视为更清晰可能更清晰形成单个资源。

在这个例子中,我认为资源是一个集体的资源,包括问题及其答案。由于这个集体资源是由问题本身唯一标识的,我会让问题控制器处理它。问题控制器中的show操作已涉及检索集体问答资源,因此您可能会将answer操作(以及可能的unanswerreanswer操作)视为update与该集体资源的类比。

以这种方式考虑资源主要取决于设计偏好,并且会根据要求进行权衡。

答案 1 :(得分:1)

您可以像questions#show这样呈现AnswersController

render :template => 'questions/show'

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

<%= form_for(@answer, :url => question_answers_url(@question, :anchor => 'answer_form')) do |f| -%>

答案 2 :(得分:-1)

有一个部分具有将数据发布到answers_controller #create action的表单。

因此,在您的问题#show page - show.html.erb中,渲染部分

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

在_answer_form.html.erb中,有一个将数据发布到答案的表单#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