怎么办“redirect_to并返回”完全退出或立即redirect_to?

时间:2014-03-12 03:45:19

标签: ruby-on-rails ruby

我将此作为我的代码:

def index
  @monkeys = Monkey.where(owner: current_user)
end

def new
  @monkey = Monkey.new name: 'Monkey 1', alive: true, owner: current_user
end

def create
  @monkey = Monkey.create monkey_params
  # Other fields and save here
end

def edit
  @monkey = Monkey.find_by(id: params[:id], owner: current_user)
  check_on_monkey_first(@monkey)
end

def update
  @monkey = Monkey.find_by(id: params[:id], owner: current_user)
  check_on_monkey_first(@monkey)

  if @monkey.update(monkey_params)
    redirect_to monkeys_path, success: 'Monkey saved'
  end
end

private
def check_on_monkey_first(monkey)
  redirect_to monkeys_path, flash: {info: "Monkey doesn't exist"} and return unless monkey
  redirect_to monkeys_path, flash: {info: "Monkey no longer exist"} and return if !monkey.alive?
end

def monkey_params
  # some_fields_here
end

我认为" ...并返回"只提前退出check_on_monkey_first,然后继续update

如果我不是Monkey的所有者,find_by将无法获得记录,并且应该执行redirect_to,因为Monkey将不存在。但它仍然会继续并在if @monkey.update(monkey_params)处中断代码,因为@monkey为零。

我如何做一个" redirect_to some_path并返回"在Ruby或Rails?如何立即停止并执行redirect_to?

3 个答案:

答案 0 :(得分:5)

可能有几种解决方案,但可能会返回一个布尔值,表明您正在触发重定向。例如:

def update
  @monkey = Monkey.find_by(id: params[:id], owner: current_user)

  if check_on_monkey_first(@monkey) and @monkey.update(monkey_params)
    redirect_to monkeys_path, success: 'Monkey saved'
  end
end

private
def check_on_monkey_first(monkey)
  redirect_to monkeys_path, flash: {info: "Monkey doesn't exist"} and return false unless monkey
  redirect_to monkeys_path, flash: {info: "Monkey no longer exist"} and return false if !monkey.alive?
  return true
end

更清晰的解决方案可能是对某些操作使用before_action(或before_filter用于Rails< v4)。但是,对于您要执行check_on_monkey_first检查的位置,它可能会降低灵活性。对于您的特定用例,您可以尝试:

before_action :check_on_monkey_first, only: [:edit, :update]

然后将check_on_monkey_first修改为:

def check_on_monkey_first
  @monkey = Monkey.find_by(id: params[:id], owner: current_user)
  redirect_to monkeys_path, flash: {info: "Monkey doesn't exist"} and return unless @monkey
  redirect_to monkeys_path, flash: {info: "Monkey no longer exist"} and return if !@monkey.alive?
end

您的update行动将成为:

def update
  if @monkey.update(monkey_params)
    redirect_to monkeys_path, success: 'Monkey saved'
  end
end

这可以让您删除需要它的操作中的检查(编辑和更新),您不必处理双重重定向,它应该自动为您设置这些操作的变量。

答案 1 :(得分:1)

您可以使用仅适用于editupdate的{​​{3}}。

class YourController < ApplicationController
  before_action :check_on_monkey_first, :only => [:edit, :update]

  # other actions ...

  def edit
  end

  def update
    if @monkey.update(monkey_params)
      redirect_to monkeys_path, success: 'Monkey saved'
    end
  end

  private
  def check_on_monkey_first
    @monkey = Monkey.find_by(id: params[:id], owner: current_user)
    if @monkey.nil?
      redirect_to monkeys_path, flash: {info: "Monkey doesn't exist"}
    elsif not @monkey.alive?
      redirect_to monkeys_path, flash: {info: "Monkey no longer exist"}
    end
  end
end

答案 2 :(得分:0)

请尝试:

private
def check_on_monkey_first(monkey)
  unless monkey
    redirect_to monkeys_path, flash: {info: "Monkey doesn't exist"}
    return 
  else
    unless monkey.alive?
      redirect_to monkeys_path, flash: {info: "Monkey no longer exist"}
      return
    end
  end
end