【问题标题】:Single Table Inheritance with Polymorthic using child class name使用子类名的多态单表继承
【发布时间】:2014-10-21 08:56:18
【问题描述】:

我有以下设置,其中 MediaItem 类具有 STI,而 ContentView 是多态的

class MediaItem < ActiveRecord::Base
  has_many :content_views, as: :media
end

class Video < MediaItem
end

class Track < MediaItem
end

class ContentView < ActiveRecord::Base
  belongs_to :media, polymorphic: true
end

在这种情况下,当执行诸如 Video.first.content_views.create 之类的操作时,media_type 列被设置为子类“Video”而不是“MediaItem”

在尝试编写这样的查询时,这会成为一个问题

ContentView.where(media_type: 'Video' )

我如何告诉 Rails 使用子类而不是 base_class?

我目前的非理想解决方案是这样写的:

class Video < MediaItem
  has_many :content_views, ->{ where(media_type: 'Video') }, as: :media, dependent: :destroy
  scope :join_content_views, -> { joins("INNER JOIN \"content_views\" ON \"content_views\".\"media_id\" = \"media_items\".\"id\" AND \"content_views\".\"media_type\" = 'Video'")}
end

并且不得不手动编写:

video.content_views.create(media_type: 'Video', media_id: video.id)

这会将 media_type 正确设置为“视频”并允许查询:

Video.joins_content_views

video.content_views

有没有人知道在 Rails 中处理这个问题的更好方法?

【问题讨论】:

  • 如果您只引用存储在一个表中的项目,为什么还要在这里使用多态引用?多态引用用于处理可能具有相同ids 的模型,因此它们被赋予显式类型。这里的类型可以从获取的条目中派生出来,并且不可能在一个表中发生id 冲突。
  • 许多其他表格使用 ContentViews,但为简单起见,我只提到了与我的问题相关的表格。

标签: ruby-on-rails activerecord polymorphic-associations sti


【解决方案1】:

你很接近,我会使用 class_name 设置子类 has_many 关系:

class MediaItem < ActiveRecord::Base
  has_many :content_views, as: :media, dependent: :destroy
  has_many :video_content_views, ->{ where(media_type: 'Video') }, class_name: 'Video', as: :media 
end

您还应该只使用type 作为列或告诉 Rails 将哪个列用于 STI,这样您就可以自动提示 content_views 类。

【讨论】:

  • MediaItem 表没有“media_type”列 - 该列在 ContentView 表中。具有 STI 的 MediaItem 已经具有列“类型”。这意味着 has_many :video_content_views 对于内容视图没有任何意义
猜你喜欢
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
相关资源
最近更新 更多