Rails Association, Scope, JoinModel
ОБНОВЛЕНИЕ: Вот как мы решили это. run MYSQL Объясните sql, сгенерированный обоими фрагментами кода:
Manifest.where (assembly_id => @ assembly.id).where (part_id => @ part.id).exists? НИКАКИХ СОЕДИНЕНИЙ И RAN БЫСТРЕЕ - ТАК ЭТО ВЫИГРАЛ!
У меня следующая ситуация:
class Assembly < ActiveRecord::Base
has_many :manifests
has_many :parts, :through => :manifests
end
class Manifest < ActiveRecord::Base
belongs_to :assembly
belongs_to :part
end
class Part < ActiveRecord::Base
has_many :manifests
has_many :assemblies, :through => :manifests
конец
Так что, как гики, мои коллеги и я вступили в спор о следующем:
По заданной детали и сборке найдите, находятся ли они в одном манифесте.
Решение первое (с использованием ассоциаций):
@part.assemblies.include? @assembly
Решение второе (с использованием областей):
Manifest.where(assembly_id => @assembly.id).where(part_id => @part.id).exists?
Решение 1 делает внутреннее соединение, чтобы получить данные, и это привело к тому, что ненавидят связующие таблицы. Но это лаконично и не безобразно.
Во втором решении не выполняется внутреннее соединение, а используются области видимости (т. Е. Предложения where), но это немного уродливо.
Первое решение называется неэффективным, а при профилировании оно работает немного медленнее.
Любые мысли о лучших практиках для этой ситуации.
Кстати, я взял код из руководств Rails, чтобы проиллюстрировать проблему.
1 ответ
Я хотел бы сделать это одним из следующих двух способов, а не из соображений производительности, просто для ясности выражения:
Есть ли какие-либо манифесты, относящиеся к @assembly и @part?
Manifest.where(assembly_id: @assembly.id, part_id: @part.id).any?
Или @assembly и @part делятся какими-либо манифестами?
(@assembly.manifests & @part.manifests).any?