ruby-on-rails - Rails - 单表继承中的多态性

标签 ruby-on-rails polymorphism single-table-inheritance

我有三个模型,PoemSong 以及 User。 用户可以对任意数量的诗歌和歌曲进行投票。

一种解决方案是创建两个关联模型 PoemVoteSongVote

class PoemVote
  attr_accessible :poem_id, :user_id
  belongs_to :poem
  belongs_to :user
end

class SongVote
  attr_accessible :song_id, :user_id
  belongs_to :song
  belongs_to :user
end

我可以调用some_poem_vote.poemsome_song_vote.song

但是,PoemVoteSongVote 本质上是相同的。如何使用单表继承从一个父 Vote 类扩展这两个表?

我正在思考以下问题:

class Vote
  attr_accessible :resource_id, :user_id
end

class PoemVote < Vote
  ...not sure what goes here...
end

class SongVote < Vote
  ...not sure what goes here...
end

如何使其工作,以便我仍然可以调用 some_poem_vote.poem 但在下面让 PoemVotes 和 SongVotes 共享一个数据库表?或者有更好的解决方案来解决我的问题吗?

最佳答案

在 Rails 中,STI 很简单:您只需在 votes 表上创建一个 type 字符串列,rails 就会处理其余的事情。要创建正确的关联,您可以执行以下操作:

class Vote
  attr_accessible :user, :votable
  belongs_to :user
  belongs_to :votable, polymorphic: true
end

...这需要在您的 votes 表中添加 votable_idvotable_type 列。请务必添加

has_many :votes, as: :votable, class_name: 'PoemVote' # or 'SongVote'

在您的关联模型上。然而,这种方法的问题在于,您必须保持警惕,不要直接使用 Vote 来创建投票,否则您将获得错误类型的关联投票。为了强制执行此操作,有一个可能的 hack :

class Vote
  attr_accessible :resource_id, :user_id

  def self.inherited( subclass )
    super( subclass )
    subclass.send :belongs_to, :votable,
                  class:  "#{subclass.name.gsub('Vote','')}"
  end
end

...但我确信(我在同样的问题上苦苦挣扎)它为代码恐怖打开了大门,因为你必须解决由继承引起的很多问题(作用域表现得很奇怪,有些库没有管理好性传播感染等)。

问题是:您真的需要性传播感染吗?如果您的投票行为相同,请不要使用 STI,只需使用多态的 belongs_to,您会省去很多麻烦。

关于ruby-on-rails - Rails - 单表继承中的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13668040/

相关文章:

ruby-on-rails - 如何正确设置我的CanCanCan权限?

ruby-on-rails - 在本地主机 :3000? 上启动 Rails 服务器后要做什么

Dart 2 类的构造函数与其他语言的多态性非常相似

ruby-on-rails-3 - 与 STI 模型的动态类型关联

php - Doctrine2 - 单表继承

ruby-on-rails - Ruby:Class.new 在 Rails 控制台中给出 "Class not initialized"错误

ruby-on-rails - Ruby on Rails 能否利用英特尔的多核处理能力?

java - 普通多态性和使用泛型的多态性有什么区别?

Haskell 具有种类和类型变量的多态性

ruby-on-rails - Rails STI 和 has_many 通过关联不起作用,SQLException : no such table