【问题标题】:How to access a variable that was created in a transaction?如何访问在事务中创建的变量?
【发布时间】:2018-12-19 05:24:04
【问题描述】:

我正在使用 Rails 4.2

我有两个数据库调用,它们都需要存在或都不存在,所以我在方法中使用事务来做到这一点。我还希望我创建的变量可以被其他地方以相同的方法访问。我只需要使用实例变量而不是局部变量吗? (为此我使用puts作为其他代码的示例,计划执行的代码要复杂得多)。

def method_name
  ActiveRecord::Base.transaction do
    record = another_method(1)
    another_method(record)
  end
  puts record.id
end

如果我运行这段代码,它会抛出这个:

undefined local variable or method `record' for #<Class:...>

但将 record 更改为 @record 将缓解这种情况。这真的是最好的选择吗?还是有更好/更优雅的方式?

【问题讨论】:

    标签: ruby-on-rails ruby variables activerecord rails-activerecord


    【解决方案1】:

    在方法范围内声明record

    def method_name
      record = nil # ⇐ THIS
    
      ActiveRecord::Base.transaction do
        record = another_method(1)
      end
      puts record.id #⇒ ID or NoMethodError if `another_method` did not succeed
    end
    

    一般来说,这种方法是一种代码味道,并且在大多数现代语言中都被禁止(其中内部record 将被关闭而外部保持不变。)正确的方法可能是让transaction 返回一个值并将其分配给记录:

    def method_name
      record, another_record =
        ActiveRecord::Base.transaction do
          [another_method(1), another_method(2)]
        end
      puts record.id if record
    end
    

    【讨论】:

    • 看起来不错。但是,如果我只想将“record”作为变量返回而不是“another_record”,我将如何编写第二个示例?
    • record = ActiveRecord::Base.transaction { another_method() }.
    • 我不确定这是否可行。我已经更新了我面临的问题的复杂性。本质上,我仍然想运行“another_method”两次,但“record”只是第一次运行时的变量名。然后当它第二次运行时,“记录”也作为变量传入。抱歉,如果这会引起混乱。
    • 我不关注。在块内分配局部变量并从块中返回它,如上所示分配外部变量。 record = ActiveRecord::Base.transaction { r = another_method(1); another_method(r); r }.
    • 啊,好吧,我认为这是最合适的写法。谢谢!
    猜你喜欢
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2019-04-15
    • 1970-01-01
    • 2021-08-13
    • 2011-04-06
    • 1970-01-01
    相关资源
    最近更新 更多