我有一个ActiveRecord模型Media,它应该能够存储关于不同类型媒体(Media :: Book,Media :: Movie,Media :: Music)的类似结构化信息.但是,每个子类都有独特的方法. # TABLE medias# string :title# string :descript
# TABLE medias # string :title # string :description # integer :media_type class Media < ActiveRecord::Base end class Media class Book < Media def reviews GoogleBooks.search(name).get_reviews end end class Movie < Media def reviews IMDB.search_movies(name).reviews end end class Music < Media def reviews Lastfm.search(name).comments end def music_video Youtube.search(name).first.embed_html end end end
如果我使用Media :: Book.new(“哈利波特”)评论,这将有效,但我希望能够使用
Media.find("Harry Potter") => Media::Book
和
Media.find("Harry Potter").reviews
我知道我应该使用media_type来实现这一点,但是我不确定是否有更好的方法来覆盖每个ActiveRecord数据库接口方法(User.medias,find,find_by_etc,where,order,limit,all)和替换每个返回值.
您可以使用ActiveRecords单表继承功能.它使用模型表上的另一列(默认为名为“type”的列)来确定每条记录的模型类型.
只需将一个字符串类型列添加到medias表中,当Rails在数据库模式中找到该列时,它将为您提供魔力.
如果AR可以将类型添加到media_type列,则还可以使用set_inheritance_column类方法更改用于单表继承的列.
class Media < ActiveRecord::Base set_inheritance_column :media_type end
然后,您将在此列中找到具有完整命名空间类名的相应对象的类名. (例如:“Media :: Book”)也就是说,您不想手动更改类型列(或您使用的任何列)的内容. ActiveRecord将自己处理它.
查看http://api.rubyonrails.org/classes/ActiveRecord/Base.html并在该页面中搜索“单表继承”以获取更多信息
编辑:刚刚意识到你的media_type列是一个整数.因此将它用于STI是行不通的.只需坚持使用字符串类型列,让AR为您完成剩下的工作.