【发布时间】:2012-12-14 20:32:05
【问题描述】:
我有一个共享许多属性的 Book 和 Download 模型,所以我的目标是从 DownloadableResource 模型继承公共属性。
看过STI,但我改用abstract base model class 方式:
-
型号:
class DownloadableResource < ActiveRecord::Base self.abstract_class = true attr_accessible :title, :url, :description, :active, :position validates :title, :url, :description, presence: true scope :active, where(active: true).order(:position) end class Book < DownloadableResource attr_accessible :cover_url, :authors validates :cover_url, :authors, presence: true end class Download < DownloadableResource attr_accessible :icon_url validates :icon_url, presence: true end -
迁移:
class CreateDownloadableResources < ActiveRecord::Migration def change create_table :downloadable_resources do |t| t.string :title t.string :url t.text :description t.boolean :active, default: false t.integer :position t.timestamps end end end class CreateBooks < ActiveRecord::Migration def change create_table :books do |t| t.string :cover_url t.string :authors t.timestamps end end end class CreateDownloads < ActiveRecord::Migration def change create_table :downloads do |t| t.string :icon_url t.timestamps end end end
迁移后,当我创建新书时,结果远非预期:
> Book.new
=> #<Book id: nil, cover_url: nil, authors: nil, created_at: nil, updated_at: nil>
有人可以解释一下如何实现抽象基模型类技术,以便 ActiveRecord 模型可以通过inheritance 共享公共代码,但可以持久保存到不同的数据库表中?
【问题讨论】:
-
一种方法是组合而不是继承。一些例子:rails-bestpractices.com/posts/17-extract-into-module
-
附带说明,即使您使用两个结构相似的表,您至少可以通过首先创建仅包含其唯一字段的所有表然后执行类似
[:books, :downloads].each do |table| change_table table do |t| t.text :description # ... end end
标签: ruby-on-rails activerecord inheritance abstract-class sti