STI полиморфный has_many использует неверное значение типа - PullRequest
0 голосов
/ 01 июля 2019

У меня есть следующие модели ИППП, у них есть полиморфная ассоциация, запрос которой строится неправильно

class Product < ApplicationRecord
  has_many :images, as: :imageable
end

class OneProduct < Product
end

class Image < ApplicationRecord
  belongs_to :imageable
end

В консоли рельсов, когда я делаю

> OneProduct.last.icon_images

Запрашиваемый запрос:

SELECT  * FROM images WHERE imageable_id = id AND imageable_type = 'Product'

Я ожидал:

SELECT * from images WHERE imageable_id = id AND imageable_type = 'OneProduct'

Я ожидаю что-то не так?

Дополнительная информация: база данных postgres.

1 Ответ

1 голос
/ 01 июля 2019

Из документации Rails:

Использование полиморфных ассоциаций в сочетании с наследованием одной таблицы (STI) немного сложнее. Чтобы ассоциации работали должным образом, сохраните базовую модель для моделей STI в столбце типа полиморфной ассоциации. Чтобы продолжить приведенный выше пример ресурса, предположим, что есть гостевые посты и посты участников, которые используют таблицу постов для STI. В этом случае в таблице записей должен быть столбец типа.

Примечание: attachable_type= method вызывается при назначении прикрепляемые. class_name присоединяемого передается как String.

class Asset < ActiveRecord::Base   
  belongs_to :attachable, polymorphic: true

  def attachable_type=(class_name)
     super(class_name.constantize.base_class.to_s)   
  end 
end

class Post < ActiveRecord::Base   
  # because we store "Post" in attachable_type now dependent: :destroy will work   
  has_many :assets,as: :attachable, dependent: :destroy 
end

class GuestPost < Post end

class MemberPost < Post end

Источник: https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations

Таким образом, в нем говорится, что вместо сохранения imageable_type = OneProduct необходимо сохранить его как только Product, и вы можете добавить столбец type в таблицу Product. Но это полностью зависит от того, что вам нужно от модели OneProduct, если default_scope на этой модели заставит ее работать без добавления столбца type, не добавляйте его в таблицу Product, и если это не работает, тогда вы можете добавить столбец и затем добавить default_scope для извлечения products.type = OneProduct при запросе к OneProduct модели.

...