xxj*_*jnn 1 ruby activerecord ruby-on-rails
特定
class Foo
has_many :bar
end
class Bar
belongs_to :foo
end
Run Code Online (Sandbox Code Playgroud)
我想要:
=> #<ActiveRecord::Relation [#<Foo id: 11, qux: 'hi', bar_id: 1, bar_name: 'blah', bar_something: 'blahblah' >, #<Foo id: 23, qux: 'hi', bar_id: 2, bar_name: 'lorem', bar_something: 'ipsum' >]>
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
> Foo.where(qux: 'hi').includes(:bar)
=> #<ActiveRecord::Relation [#<Foo id: 11, qux: 'hi', bar_id: 1 >, #<Foo id: 23, qux: 'hi', bar_id: 2 >]>
Run Code Online (Sandbox Code Playgroud)
但它不会加载子记录.似乎只是在需要的时候坚持下去.
必须有比这更优雅的东西吗?
Foo.where(qux: 'hi').includes(:bar).to_a.map do | f |
f.keys.each { |k| f[ k.to_s ] = f.delete(k) if k.class == :symbol }
Bar.column_names.except('id','foo_id').each do | ba |
ba_name = 'bar_' + ba
f.merge({ba_name => f.bar.send(ba.to_sym)})
end
f
end
Run Code Online (Sandbox Code Playgroud)
includes(:bar)在这种情况下,延迟加载子记录bar.这是避免n + 1个查询的一种方法(这样你就不会为每个实例运行一个查询foo).你可以访问它.
Foo.where(qux: 'hi').each do |foo|
puts foo.bar.inspect
end
Run Code Online (Sandbox Code Playgroud)
如果你想得到他们所有的foos地方bar.qux = hi,那么去其他地方:
Bar.joins(:foo).where(foo: { qux: 'hi' })
Run Code Online (Sandbox Code Playgroud)