Я страдаю от варианта проблемы, описанной здесь:
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' сценариях).
Существует ли жизнеспособное обходное решение?
что-то вроде
:conditions => { :this_table => { :state => 1 } }
Используете ли вы какие-либо поля из таблиц :include
в запросе (как :условия / :order и т. Д.)? Если нет, и вам просто нужно загрузить записи, вы можете сделать это с помощью отдельного запроса:
records = Bar.all(:joins => ..., :conditions => ..., ...)
Bar.send(:preload_associations, records, [:association1, :association2 ... ])
preload_associations
является защищенным методом (см. more в этом ответе), но использование :joins и :include вместе обычно создает огромный SQL-запрос, который далек от управления.
Вместо того, чтобы использовать: include, с ключом: joins вы можете явно написать соединение и дать ему свой собственный псевдоним таблицы. Вы должны указать соединение вручную, но это сделает ваши требования полностью однозначными. например:
Bar.all(:joins => "INNER JOIN foos AS my_foos ON my_foos.bar_id = bars.id", :conditions => "my_foos.state = 1")