没有明确接收者的“交易做”

时间:2019-05-08 15:41:06

标签: ruby-on-rails activerecord transactions

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

  • ActiveRecord::Base.transaction do
  • User.transaction do
    用户来自ActiveRecord :: Base
  • @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始终是模型实例?

1 个答案:

答案 0 :(得分:0)

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

class Thing
  def foo
    inspect
  end
end

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

我有权假设那个自我。其实没有必要,因为   模型实例方法的范围,自我始终是模型   默认情况下是实例?

在ruby中总是有一个隐式接收者(自己)。它是什么取决于上下文。在类方法中是其类。如果您不在类或模块中,则为“主要”(全局对象)。

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);