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

ind*_*dex 3 ruby ruby-on-rails

我有这个作为我的代码:

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
Run Code Online (Sandbox Code Playgroud)

事情是我认为"......并且只是提前退出" - 退出check_on_monkey_first然后继续update.

如果我不是的所有者Monkey,find_by不会得到记录,应该做一个redirect_to因为Monkey不存在.但它仍然继续并且if @monkey.update(monkey_params)因为@monkey是零而破坏了代码.

如何在Ruby或Rails中执行"redirect_to some_path并返回"?如何立即停止并执行redirect_to?

Mar*_*ach 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
Run Code Online (Sandbox Code Playgroud)

一个更干净的解决方案可能是使用像before_action(或before_filterRails <v4)这样的东西来执行某些操作.但是,它可能会降低您在何处执行check_on_monkey_first检查的灵活性.对于您的特定用例,您可以尝试:

before_action :check_on_monkey_first, only: [:edit, :update]
Run Code Online (Sandbox Code Playgroud)

然后修改你的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
Run Code Online (Sandbox Code Playgroud)

你的update行动将成为:

def update
  if @monkey.update(monkey_params)
    redirect_to monkeys_path, success: 'Monkey saved'
  end
end
Run Code Online (Sandbox Code Playgroud)

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