Ruby on rails “怎么做?”;将“U重定向到并返回”;要完全退出或立即将_重定向到?

Ruby on rails “怎么做?”;将“U重定向到并返回”;要完全退出或立即将_重定向到?,ruby-on-rails,ruby,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

我将此作为我的代码:

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
问题是我认为“…并返回”只会提前退出
首先检查\u monkey\u
,然后继续执行
更新

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
如果我不是
Monkey
的所有者,
find\u by
将不会获得记录,并且应该将
重定向到
,因为
Monkey
将不存在。但是如果@monkey.update(monkey_params)
,它仍然会继续并在
处中断代码,因为
@monkey
为零

如何在Ruby或Rails中实现“重定向到某个路径并返回”?如何立即停止并重定向到?

请尝试:

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

可能有几种解决方案,但其中一种可能是返回一个布尔值,指示您正在触发重定向。例如:

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\u action
(或
before\u filter
for Rails检查的灵活性。对于您的特定用例,您可以尝试:

before_action :check_on_monkey_first, only: [:edit, :update]
然后首先将您的
检查修改为:

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
您的
更新操作将变成:

def update
  if @monkey.update(monkey_params)
    redirect_to monkeys_path, success: 'Monkey saved'
  end
end
这将允许您在需要它的操作(编辑和更新)中删除签入,您不必处理双重重定向,它将自动为您设置这些操作的变量。

您可以使用该选项,该选项仅适用于
编辑
更新

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
class YourController[:edit,:update]
#其他行动。。。
定义编辑
结束
def更新
如果@monkey.update(monkey_参数)
重定向到Monkey路径,成功:“Monkey saved”
结束
结束
私有的
def首先检查猴子
@monkey=monkey.find_by(id:params[:id],所有者:当前用户)
如果@monkey.nil?
重定向到猴子路径,flash:{info:“猴子不存在”}
elsif not@monkey.live?
重定向到猴子路径,flash:{info:“猴子不再存在”}
结束
结束
结束

我也想这样做,但除了CRUD之外,我还有其他更多的操作将使用相同的方法,并且不是所有的操作都在代码的开头进行了查找检查。我还想做第二个操作,但除了CRUD,我还有其他更多的操作会使用相同的方法,但并不是所有的操作都在代码的开头有find_by-and-check。所以我要试试第一个。但有了这种解决方案,这是否意味着没有“立即重定向到并停止执行代码”?@index-Correct,目前没有导致这种情况的内置操作。
before\u action
与此最为接近,因为它将检测是否调用了
重定向\u至
,如果调用了,它将不会调用它正在执行的操作。我现在明白了。我会记住这一切的。第一个是我现在使用的想法-我所做的是在
edit
update
方法上
return
返回,除非先检查猴子(@monkey)
。我想这里的
return
仍然只会退出
先检查猴子(monkey)