redirect_to 可能在 rails 中验证失败后?

redirect_to after failed validation possible in rails?

这是我的测试:

def test_words_with_non_letters_are_rejected
    visit '/plays'
    click_link_or_button 'Play New Word'

    fill_in 'play[word]', :with => 'boom!'
    click_link_or_button 'Play!'
    assert page.has_css?("#errors")

    fill_in 'play[word]', :with => '37nums'
    click_link_or_button 'Play!'
    assert page.has_css?("#errors")

    fill_in 'play[word]', :with => 'ok'
    click_link_or_button 'Play!'
    assert_equal '/plays', current_path
end

这是我的控制器:

class PlaysController < ApplicationController
  def index
    @plays = Play.all
  end

  def new
  end

  def create
    if params[:play][:word].blank?
      flash[:error] = 'blank'
      redirect_to new_play_path
    else
      @play = Play.create(plays_params)
      redirect_to plays_path
    end
  end

  private

  def plays_params
    params.require(:play).permit(:word)
  end
end

这是我的模型:

class Play < ActiveRecord::Base

  before_save { self.word = word.downcase }

  validates :word, presence: true, length: { maximum: 7 }
  # validates_format_of :word, :with => 

  def letter_scores
    {"A"=>1, "B"=>3, "C"=>3, "D"=>2, "E"=>1, "F"=>4, "G"=>2, "H"=>4, "I"=>1, "J"=>8,
     "K"=>5, "L"=>1, "M"=>3, "N"=>1, "O"=>1, "P"=>3, "Q"=>10, "R"=>1, "S"=>1, "T"=>1,
     "U"=>1, "V"=>4, "W"=>4, "X"=>8, "Y"=>4, "Z"=>10}
  end

  def score(setting_hash = {:word_multiplier => :single})
    word_multiplier = {:single => 1, :double => 2, :triple => 3}

    word.upcase.chars.inject(0){|sum, letter| sum + letter_scores[letter]} * word_multiplier[setting_hash[:word_multiplier]]
  end
end

所以我在为 Play 模型的 validates_format_of 验证编写正则表达式时遇到了问题。另外,我不知道如何在验证失败后重定向到正确的页面。我尝试在创建控制器中写入两个 redirect_to,但我收到一条错误消息,提示 redirect_to 过多。

在创建操作的 else 条件中,我尝试在 Play.create 行之后写这个:

redirect_to plays_path if @play
flash[:error] "Something when wrong during Play creation"
redirect_to new_play_path

我做错了什么?

尝试将 create 方法更改为:

  def create
    if params[:play][:word].blank?
      flash[:error] = 'blank'
      redirect_to new_play_path
    else
      @play = Play.new(plays_params)
      if @play.save
        redirect_to plays_path
      else
        flash[:error] "Something when wrong during Play creation"
        redirect_to new_play_path
      end
    end
  end

Rails 禁止您在操作中多次使用 renderredirect 。这些方法不会停止执行流程,因此您试图在您的示例中执行两次。相反,您可以在重定向后立即 return。像这样

redirect_to plays_path and return if @play

我建议以这种方式重构 create 方法

def create
  @play = Play.create(plays_params)
  if @play.save
    redirect_to plays_path
  else
    flash[:error] = @play.errors.full_messages
    redirect_to new_play_path 
  end
end

因此您可以在闪存中获取所有验证错误消息。虽然这不是使用 flash 的最佳方式,但通常 return 特定消息更好。喜欢

flash[:error] = "Can't save play"