15

我有一个共享许多属性的BookDownload模型,所以我的目标是从DownloadableResource模型继承公共属性。
看了一下STI,但我采用了抽象基模型类的方式:

  • 楷模:

    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 模型可以通过继承共享公共代码,但可以持久保存到不同的数据库表?

4

2 回答 2

14

通过将模型声明为抽象,您实际上是在说没有基础表并且您希望允许子类化。这意味着:

  • 你不需要downloadable_resources桌子
  • Book.table_name 打印books而不是downloadable_resources

正如@Finbarr 已经提到的,这也意味着模型BookDownload模型都需要在其表中具有所有属性。

那么这实际上有什么用呢?在我看来不是很多。您可以共享验证、范围等,但您可以通过包含自定义模块更轻松地实现所有这些。

To solve your problem I would probably go with a different approach. I would create another model called DownloadableContent that would be self contained. It would include validations and the table would have all of the attributes. And finally models Book and Download would have a polymorphic has_one relation to the DownloadableContent model.

You could go with the STI approach but I generally don't like mixing all of the custom attributes together.

于 2012-12-30T14:28:57.410 回答
5

在这种情况下不应该有一张downloadable_resources桌子。您的书籍和下载表都应该声明他们需要的所有字段。

于 2012-12-30T06:48:22.873 回答