поиск через объединенную полиморфную ассоциацию с определенным именем таблицы

#ruby #activerecord #polymorphic-associations

#ruby #activerecord #полиморфные ассоциации

Вопрос:

у меня есть две модели

 class Profession < ApplicationRecord
    has_many :users
end

class User < ApplicationRecord

  self.table_name = 'accounts'

  belongs_to :scope, polymorphic: true

end 
  

и запрос:

 Profession.joins(:users).where(accounts: {scope: some_scope_variable })
  

когда я запускаю это, я получаю

 Mysql2::Error: Unknown column 'accounts.scope' in 'where clause'
  

что я также пробовал, так это

 Profession.joins(:users).where(users: {scope: some_scope_variable })
  

но это также не работает и выдает аналогичную ошибку

 Mysql2::Error: Unknown column 'users.scope' in 'where clause'
  

Ответ №1:


Согласно документации, полиморфные ассоциации основаны на двух столбцах, присутствующих в модели. Пример

 class User < ApplicationRecord
  belongs_to :thingable, polymorphic: true
end
  

Эти столбцы должны существовать на users :

  • thingable_id
  • thingable_type

Если вы хотите запросить их через ассоциацию, вы можете использовать столбцы напрямую, например:

 Profession.joins(:user).where(users: { thingable_id: 42, thingable_type: 'Foo' })
  

Кроме того, я бы пересмотрел название scope , поскольку оно уже используется Rails.


Редактировать:

После отправки приведенного выше ответа я начал понимать ваш вопрос, извините за это.

Я воспроизвел его и заставил его работать следующим образом:

 class Profession < ApplicationRecord
  has_many :users, as: :thingable # <-- this is missing in your case
end
  
 class User < ApplicationRecord
  self.table_name = 'accounts'

  belongs_to :profession
  belongs_to :thingable, polymorphic: true
end
  

Теперь мы можем сделать это:

 Profession.joins(:users).where(accounts: { age: (20..30) })
  

Предложение WHERE — в объединенной таблице преобразуется в SQL без каких-либо действий и проверок:

 WHERE `accounts`.`age` BETWEEN 20 AND 30
  

В то WHERE время как предложение -для собственных столбцов иногда волшебным образом изменяется:

 User.where(thingable: 42)
  

результаты в

 WHERE `accounts`.`thingable_id` = 42
--                         ^^^ added by Rails
  

Итак, если мы хотим выполнить фильтрацию по любому из этих полиморфных столбцов, мы делаем

 Profession.joins(:users).where(accounts: { thingable_id: 111 })
  

Комментарии:

1. эти два столбца определенно существуют. where scope: some_scope_variable работает при вызове в пользовательской модели

2. Я понимаю… кажется, это проблема, когда у пользователя есть пользовательское имя таблицы… Я попытаюсь воспроизвести все это сейчас. : 1:

3. я прочитал ваш обновленный ответ, и он, должно быть, как-то ошибочен, потому что раньше этот запрос работал без объявления имени таблицы_ (когда таблица учетных записей использовалась моделью учетной записи). другое дело, чтобы заставить его работать так, как вы сказали, мне нужно знать все возможные типы, которых я не знаю

4. я собираюсь решить это, перейдя Profession.joins(:user).merge(User.where(scope: variable)) . тогда это работает. я думаю, что у AT есть проблемы с использованием table_name с объединенными таблицами

5. : 1: Я протестировал ваше решение, оно выдает тот же SQL-запрос, .where(accounts: { thingable_id: 111 }) что и . Приятно!