如何为ActiveRecord模型定义rescue_from-type处理函数?

时间:2019-03-26 01:41:20

标签: ruby-on-rails ruby

在Rails中进行开发5.2.2.1。我想为模型定义一个“全局”救援处理程序,以便可以捕获NoMethodError并采取适当的措施。我发现控制器可以使用rescue_from来做到这一点,但是模型却不能。知道Rails开发人员是聪明人;)我认为一定有一些充分的理由,但是我仍然感到沮丧。到处搜寻,我什至找不到任何人问如何做到这一点的例子,而其他人要么告诉他们如何做,为什么他们不能做,或者为什么他们不想要。也许是因为救援处理程序无法将值返回给原始调用方?

这就是我要做的事情:我需要重构我的应用程序,以便将过去曾经是单个模型的应用程序拆分成两个模型(我们分别称为Orig和New)。简而言之,我想这样做,以便在针对Orig对象调用属性getter方法(例如)时,如果该属性已移至New,那么我可以捕获此错误并改为调用new.getter(了解Orig现在belongs_to新增)。该解决方案的灵感来自于我在Perl5的AUTOLOAD功能中做这种事情的经验。

任何有关如何完成此操作的想法都将受到赞赏。也许我只需要为所有移动的属性分别定义getter / setter。

2 个答案:

答案 0 :(得分:0)

覆盖method_missing :)!?

您可以尝试覆盖method_missing方法。这可能会导致令人困惑的错误,但是重写该方法肯定会在我所知的至少一颗宝石中发挥巨大作用。

我不想调用类new,因为它是一个保留关键字,可能会造成混淆。因此,我将类名称更改为Upgraded

这应该让您入门。

class Upgraded
  def getter
    puts "Congrats, it gets!"
  end
end

class Original
  def initialize
    @new_instance = Upgraded.new
  end

  def method_missing(message, *args, &block)
    if message == :attribute_getter
      @new_instance.send(:getter, *args, &block)
    else
      super
    end
  end

  def respond_to_missing?(method_name, *args)
    method_name == :attribute_getter or super
  end
end

c = Original.new
c.attribute_getter
  • 您将不得不更改getter和setter方法的名称。因为您具有belongs_to关联,所以可以使用它。

或者您可以尝试仅使用委托_来

就像@mu_is_too_short一样,您可以尝试这样的事情吗?

class Original < ApplicationRecord
 belongs_to :upgraded
 delegate :getter_method, :to => :upgraded 
end

class Upgraded < ApplicationRecord
  def getter_method
  end
end

答案 1 :(得分:0)

显然,我需要知道的是“ delegation”一词。在Ruby和Rails中,似乎有很多种方法可以做到这一点,我应该期望Ruby的实现方法比Perl5更干净,更优雅,更进化。特别是,最新版本的Rails提供了“ delegate_missing_to”,这似乎正是我在该用例中所需要的。