2016-04-30 141 views
2

我有一個ActiveJob,其中一些參數已經用GlobalID進行了序列化。在ActiveJob中急切加載

執行工作時,我該如何加載一些相關模型?

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幾種模式,並smetimes我甚至有N + 1度的問題,而它(在不同的例子,沒有預先加載)

回答

0

我如果foobar是單數項目,不明白爲什麼這會導致N + 1問題。

否則,ActiveJob預先加載的作品就像ActionControler,或其他任何地方:

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方法。活動作業需要在將對象插入隊列之前序列化一個對象,因此有時候通過id引用可以更簡單,更容易地從數據庫中獲取對象。

+1

因此,如果我們需要Eager Loading,基本上[globalID](http://edgeguides.rubyonrails.org/active_job_basics.html#globalid)技巧就變得毫無用處了。 –