Путаница в полиморфных отношениях

#mysql #ruby-on-rails #ruby #activerecord

#mysql #ruby-on-rails #ruby #activerecord

Вопрос:

Итак, я не понимаю, как ActiveRecord справляется с этим, и надеялся, что кто-нибудь сможет дать мне некоторое представление.

У меня есть таблица, которая имеет полиморфные отношения. Мы будем называть это выбором таблицы. Там я определил:

 belongs_to :chooseable, polymorphic: true
  

У меня есть две модели, давайте назовем одну movies, а другую plays. Там у меня есть: has_many :choices as: chooseable, dependent: destroy

В модели с полиморфными отношениями у меня есть две области:

   scope :with_movies, -> {
    includes(:movies)
      .where("chooseable_type": "Measure")
  }
  scope :with_shows, -> {
    includes(:shows)
      .where(shows: { hidden: false })
  }
  

Что меня смущает, так это то, что если я скажу users.choices.with_movies, и я оставляю условие chooseable_type where, AR отказывается от меня и говорит:

 Unknown column 'choices.chooseable_type' in 'where clause': SELECT `movies`.* FROM `movies` WHERE `choices`.`chooseable_type` = 'Movie' AND `movies`.`id` IN (728) 
  

Тем не менее, во второй области с помощью_shows мне не нужно определять chooseable_type — он работает нормально. Еще более запутанным является то, что если я удалю предложение where, with_shows , оно также не будет работать.

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

Ответ №1:

Проблема в том, что Rails пытается сделать это наилучшим образом, создавая для вас результирующий сложный запрос, и он решает

 .where("chooseable_type": "Measure")
  

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

 .where("movies.chooseable_type": "Measure") 
  

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

1. Итак, поскольку в другой области есть предложение where для таблицы shows, он знает, что нужно применить предложение chooseable_type к таблице shows, даже если оно явно не указывает на это? Это так странно для меня.

2. Попытайтесь puts with_shows.to_sql увидеть построенный запрос.