开发者

Rendering different controller actions in Rails when using resource-oriented controllers

Say I'm making a Q&A site like StackOverflow. I have two resources: Question and Answer. I'm using default Rails RESTful resource routes, so each resource has its own controller and methods for creating it.

In the /questions/show view, I want to allow the user to submit an answer for the particular question. The form will POST to /answers, which will get routed as a request to the AnswersController with a call to the create method.

If the answer was created, I can simply redirect back to the original question. However, I'm running into trouble dealing with validation failures on the answer object. I need to render the /question/show view and show the validation errors for the answer object. It's开发者_Python百科 not clear to me how to best do this.

Here are example snippets of what the two controllers might look like.

class AnswersController < ApplicationController
  def create
    @answer = Answer.new(params[:answer])
    if @answer.save
      redirect_to @answer.question
    else
      # What should go here??
    end
  end
end

class QuestionsController < ApplicationController
  def show
    @question = Question.find(params[:id])
    @answer = Answer.new(:question_id => @question.id)
  end
end

What should go in the else clause of the AnswersController's create method? A redirect seems wrong, since the error is really caused by the same request. Calling something like render :template => 'questions/show' seems wrong too, since I have to initialize any instance variables that the template depends on.

This style of having separate actions for calling GET to view the form for creating an object and calling POST to actually create the object seems to work well within a single controller.

How can it be done across controllers?


Try this on for size. It redirects, but passes back the dodgy answer object full of errors.

class AnswersController < ApplicationController
  def create
    @answer = Answer.new(params[:answer])
    # stash the dodgy answer if it failed to save
    session[:answer] = @answer unless @answer.save
    redirect_to @answer.question
  end
end

class QuestionsController < ApplicationController
  def show
    @question = Question.find(params[:id])
    # if we have one stashed in the session - grab it from there
    # because it probably contains errors
    @answer = session[:answer] || Answer.new(:question_id => @question.id)
  end
end

Some details need adding (eg clearing it from the session when done) etc

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜