:include и искажение таблицы

Я страдаю от варианта проблемы, описанной здесь:

ActiveRecord присваивается, псевдонимы таблицы для ассоциации присоединяется справедливо непредсказуемо. Первая ассоциация к данной таблице сохраняет имя таблицы. Дальнейшие соединения с ассоциациями к той таблице используют псевдонимы включая названия ассоциации в пути..., но разработчикам приложения свойственно не знать о [других] соединениях при кодировании времени.

В моем случае я кусаюсь токсичным соединением has_many и: включать. Много таблиц в моей схеме имеют a state столбец и has_many хотят указать условия на том столбце: has_many :foo, :conditions => {:state => 1}. Однако, так как столбец состояния появляется во многих таблицах, я снимаю неоднозначность путем явного определения имени таблицы: has_many :foo, :conditions => "this_table.state = 1".

Это хорошо работало до сих пор, когда для эффективности я хочу добавить :include предварительно загружать довольно глубокое дерево данных. Это заставляет таблицу быть искаженной несовместимо в различных путях выполнения кода. Мое чтение билетов, на которые ссылаются выше, состоит в том, что эта проблема не и не будет решена в направляющих 2.x. Однако я не вижу способа применить предложенное обходное решение (для определения искаженного имени таблицы явно в запросе). Я рад указать псевдоним таблицы явно в has_many операторе, но я не вижу способа сделать так. По сути, обходное решение не кажется применимым к этой ситуации (ни, я предполагаю во многих 'named_scope' сценариях).

Существует ли жизнеспособное обходное решение?

9
задан dondo 2 June 2010 в 21:42
поделиться

3 ответа

что-то вроде

:conditions => { :this_table => { :state => 1 } }
0
ответ дан 5 December 2019 в 01:42
поделиться

Используете ли вы какие-либо поля из таблиц :include в запросе (как :условия / :order и т. Д.)? Если нет, и вам просто нужно загрузить записи, вы можете сделать это с помощью отдельного запроса:

records = Bar.all(:joins => ..., :conditions => ..., ...)
Bar.send(:preload_associations, records, [:association1, :association2 ... ])

preload_associations является защищенным методом (см. more в этом ответе), но использование :joins и :include вместе обычно создает огромный SQL-запрос, который далек от управления.

0
ответ дан 5 December 2019 в 01:42
поделиться

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

Bar.all(:joins => "INNER JOIN foos AS my_foos ON my_foos.bar_id = bars.id", :conditions =>  "my_foos.state = 1")
3
ответ дан 5 December 2019 в 01:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: