2016-01-04 4 views
1

С учетом созданного отношения, как я могу получить доступ к элементу отношения, которое соответствует некоторому (очень простому) условию без запуска дополнительного запроса к базе данных?Доступ к произвольному элементу ActiveRecord :: AssociationRelation без дополнительного запроса db

class Foo < ActiveRecord::Base 
    has_many :bars 
end 

class Bar < ActiveRecord::Base 
    belongs_to :foo 
end 

joined = Foo.all.joins(:bars).select('foos.*, bars.baz') 

a = joined.to_a # no additional query 
b = joined.find_by_baz(1) # these will both generate additional queries 
c = joined.find_by_baz(4) # even though the data is already available 

Возможно, у меня может быть что-то простое, но есть ли способ получить доступ к произвольному элементу ассоциации на произвольное значение?

Возможно, обходное решение, которое я подумал, это загрузить ассоциацию в массив, индексированный значением, которое меня интересует. Это кажется более хрупким, чем идеалом.

+0

Данные не 'уже доступны', пока вы не попытаетесь изучить записи. Поэтому 'a = join.to_a' выполняет поиск. Если вы хотите избежать последующего поиска db, используйте записи в массиве «a» ... 'b = a.select (bas: 1) .first' – SteveTurczyn

+0

, который является действительным пунктом о' уже доступном', о котором я знал но не сделал явного, спасибо за упоминание. и использование формы массива с выбором, похоже, является способом выхода. – jay

ответ

0

Есть несколько способов фильтрации данных, один из базы данных, которая является то, что вы сделали: joined.find_by_baz(1) другой фильтрации на массив, который вы можете сделать:

joined.to_a.select{|a| a.baz == 1} 

Это не будет делать дополнительный вызов базы данных, но будет использовать native select within the Enumarable module

Лично я бы пошел с базой данных.

+0

Проблема с подходом к базе данных заключается в том, что для моего конкретного приложения это приведет к созданию сотни или около того запросов для этой части вместо 1., что может указывать на необходимость реорганизации структуры данных и я могу выполнить это с присоединением, как они есть, но это было бы довольно уродливо. – jay

+0

to_a.select выполняет в основном мое обходное решение, но более элегантным способом. он действительно решает мою проблему без дополнительного запроса, хотя, если кто-то скоро появится с «join.find_by_baz_without_extra_query (1)», я соглашусь с ним :) – jay

Смежные вопросы