#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 })
что и . Приятно!