Скажем, у меня есть отношения в Rails к таблице, которая использует STI нравится:Rails 4.2: Нетерпеливый заряжания has_many связь с ИППП
class Vehicle < ActiveRecord::Base; end
class Car < Vehicle; end
class Truck < Vehicle; end
class Person < ActiveRecord::Base
has_many :cars
has_many :trucks
has_many :vehicles
end
... и я хочу, чтобы загрузить Личность и все ее автомобилей и грузовиков в одном запросе. Это не работает:
# Generates three queries
p = Person.includes([:cars, trucks]).first
... и это близко, но не повезло здесь:
# Preloads vehicles in one query
p = Person.includes(:vehicles).first
# and this has the correct class (Car or Truck)
p.vehicles.first
# but this still runs another query
p.cars
я не мог сделать что-то подобное в person.rb:
def cars
vehicles.find_all { |v| v.is_a? Car }
end
, но затем Person#cars
больше не является прокси-сервером коллекции, а я , как.
Есть ли элегантное решение?
EDIT: добавление этого объекта дает мне элементы, которые я хочу в массивах, с одним запросом; это действительно очень близко к тому, что я хочу:
def vehicle_hash
@vehicle_hash ||= vehicles.group_by {|v|
v.type.tableize
}
end
%w(cars trucks).each do |assoc|
define_method "#{assoc}_from_hash".to_sym do
vehicle_hash[assoc] || []
end
end
и теперь я могу сделать Person.first.cars_from_hash
(или найти лучшее название для моей несинтетической прецеденту).
Да, ударный удар может быть заметным; Я делаю это для шести классов ИППП у каждого из двух родителей. Хм ... что бы было связано с созданием фактических отношений для assocation_cache? – Nate
Я добавил вариант вашего решения вверх. Смутно разумно? Любопытно, однако: зачем вам менять транспортные средства, чтобы взять тип STI? (В моем случае я обычно загружаю все свои типы STI для каждого запроса.) – Nate
Выглядит так же хорошо, как и любой другой. Хотя в результате вы все еще не получаете отношения. Я искал решение, которое добавляло наименьшие методы и наименьшую степень сложности. Ваше решение, кажется, добавляет слишком много для моего вкуса. Я также добавлю изменение. – evanbikes