【问题标题】:Eager Load in ActiveJobActiveJob 中的急切负载
【发布时间】:2016-08-25 17:05:20
【问题描述】:

我有一个 ActiveJob,其中一些参数已使用 GlobalID 进行序列化。

在执行工作时,我怎样才能急切地加载一些相关的模型?

class Foo
  has_one :bar
end

class Bar
  belongs_to :foo
  field :some_field
end

class MyJob < ApplicationJob
  queue_as :default

  def perform(foo)
    # How can I eager load bar ?
    foo.bar.some_field # Hits the DB again without eager loading
  end
end

这只是一个简单的例子,但在我的应用程序中我需要 eager_load 几个模型,有时我什至没有它会遇到 N+1 个问题(在不同的例子中,没有预先加载)

【问题讨论】:

    标签: ruby-on-rails mongoid ruby-on-rails-5


    【解决方案1】:

    如果 foobar 是单数项,我不明白为什么这会导致 N+1 问题。

    否则,像 ActionControler 或其他任何地方一样,急切加载在 ActiveJob 中工作:

    class Foo
      has_many :bars
    end
    
    class Bar
      belongs_to :foo
      field :some_field
    
      def title
        "Title"
      end
    end
    

    您会像这样急切地加载:bars 关联:

    foo = Foo.find(id).includes(:bars)
    
    foo.find_each do |foo_item|
       # Process foo.bar.title without needing another query...
    end
    

    此外,如果可能,您应该将原始值(例如 id )而不是对象传递给您的 perform 方法。 Active Job 需要在将对象插入队列之前对其进行序列化,因此有时通过 id 引用从数据库中获取对象更简单、更容易。

    【讨论】:

    • 所以如果我们需要急切加载,globalID 技巧基本上就没有用了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    相关资源
    最近更新 更多