没有显式接收方的"事务执行"



根据文档,在Rails模型中,事务是在从ActiveRecord::Base或此类的任何实例上降生的类上进行的。关于该主题的一些博客文章列出了以下替代方法:

  • ActiveRecord::Base.transaction do

  • User.transaction do用户从活动记录::基地下降

  • @user.transaction do@user 是 User 的实例

  • self.class.transaction do在任何 model.rb 中,其中 self 是例如用户

  • self.transaction do在任何 model.rb 中,其中 self 是例如用户的实例)

但是,我错过了此列表中的另一个变体:在model.rb中仅transaction do怎么样?

class User < ApplicationRecord
def foo
transaction do
# do stuff
end
end
end

我是否可以假设,self.并不是真正必要的,因为在模型实例方法的范围内,self 默认情况下始终是模型实例?

在 Ruby 中,实例方法中的隐式接收者始终是实例:

class Thing
def foo
inspect
end
end

irb(main):026:0> Thing.new.foo
=> "#<Thing:0x007fde95955828>"

我假设的对吗,自我。 并不是真的必要,因为在 模型实例方法的范围,self 始终是模型 实例默认?

红宝石中总有一个隐含的接受者(自我)。它是什么取决于上下文。在类方法中,它是类。它的"main"(全局对象),如果你不在类或模块中。

class Foo
inspect
end
# => "Foo"
def foo
inspect
end
# => "main"

您只需要在需要消除歧义的地方显式使用self(例如self.class)。但是在许多情况下,它可以帮助提高代码的可读性。

上述所有选项在功能上几乎是等效的:

  • ActiveRecord::Base.transactiondatabase.ymlENV["DATABASE_URL"]连接到该环境的数据库。
  • 如果您希望每个模型类具有不同的连接或只是不喜欢键入,则可以使用User.transactionclass.transaction。它真正做的只是connection.transaction(options, &block).
  • 实例级别self.transaction@user.transaction只是类方法的代理。它真正做的只是self.class.transaction(options,&block);

最新更新