Ruby on Rails:有没有可能静态地强制一个示例方法只能在一个“持久化的”而不是“改变的”示例上调用?

krcsximq  于 2023-02-18  发布在  Ruby
关注(0)|答案(2)|浏览(201)

在Rails中,您可以执行以下操作:

class FooBar < ApplicationRecord
  def baz
    unless persisted? && !changed?
      raise SomeError, "This FooBar must be persisted and unchanged."
    end

    # do something
  end
end

但是我更希望避免遇到运行时错误,并且我不希望由于检查记录是persisted?而不是changed?而受到(非常轻微的)性能影响。有没有一种方法可以静态地强制示例方法只能在persisted?而不是changed?示例上调用?
我查看了ActiveRecord::Dirty,但找不到任何类似我正在寻找的内容。

jtw3ybtb

jtw3ybtb1#

在Ruby中,“静态强制”并不是你真正要做的事情,它是一种弱类型的动态语言,所以没有编译时检查。
您真的应该更仔细地考虑一下这个方法需要什么样的流--如果这个方法在使用错误的输入调用时应该静默地退出,那么您应该添加一个guard语句并提前返回。

class FooBar < ApplicationRecord
  def baz
    if !persisted? && changed?
      return # this will just return nil
    end
    # do something ...
  end
end

这仍然需要调用者知道方法可能不会返回预期的值,并处理它,以便您不会只得到NoMethod错误。
如果在新记录上调用此方法是一个异常事件,并且程序员应该得到通知并能够挽救错误,则应该引发异常。
但我更希望避免遇到运行时错误
异常不等于运行时错误,调用者可以挽救异常。这实际上不是一个推理如何构建代码的好方法。为任务选择正确的控制流,不要害怕异常。
我宁愿不必承担检查记录是否持久化以及是否未更改的(非常轻微的)性能损失。
这是完全不相关的,两者都只是检查布尔属性。

eqoofvh9

eqoofvh92#

如果不需要引发错误,只需从此方法返回
您不会感觉到性能的提高,但我认为如果使用单独的正条件,而不是unless&&!,则可读性会更强

class FooBar < ApplicationRecord
  def baz
    return if changed?
    return if new_record?

    # do something
  end
end

请记住,new_record?!persisted?不同,因为存在destroyed?状态

相关问题