ActiveRecord
使用与每个对象相关的外部数据进行建模,我正在尝试找出一种干净、高效的方法来实现这一点。
class State < ActiveRecord::Base
def counties
@counties ||= fetch_external_data(state: name)['counties']
end
end
State.find_by_name('Alabama').counties
但是如果我有一个对象集合(通过
ActiveRecord::Relation
),则这将导致对该外部数据源的N+1查询。
State.where(name: %w[Alabama Georgia]).map(&:counties)
理想情况下,我希望从外部数据源加载所有数据,然后
counties
实例方法从这个“共享”对象访问数据。我可以使用一个类方法:
class State < ActiveRecord::Base
attr_accessor :counties
def self.with_counties
# Get external data for all states in our scope
counties = fetch_external_data(states: pluck(:name))
# Group by the state
counties_by_state = counties.group_by { |c| c['state'] }
# Now hydrate all of the state models and set the counties
all.map do |state|
state.counties = counties_by_state.dig(state.name, 'counties')
end
end
end
虽然这是可能的,但它使我无法在使用后进一步链接作用域
State.where(name: %w[Alabama Georgia]).with_counties
ActiveRecord::关系
当记录被冻结时可以访问的对象)?如果我有一个表示这个外部数据接口的类,那么我可以在这个类上定义一些方法来让它工作吗
State.includes(:counties)
State.eager_load(:counties)
?