【问题标题】:How to implement Active Record inheritance in Ruby on Rails?如何在 Ruby on Rails 中实现 Active Record 继承?
【发布时间】:2009-10-21 05:50:22
【问题描述】:

如何实现活动记录的继承?

例如,我想要一个动物类、狗类和猫类。

模型和数据库表映射如何?

【问题讨论】:

  • 你可能想接受一个答案

标签: ruby-on-rails database inheritance activerecord model


【解决方案1】:

Rails 支持单表继承。

来自AR docs

Active Record 允许继承 将类的名称存储在 默认情况下名为“类型”的列 (可以通过覆盖来改变 Base.inheritance_column)。这表示 继承看起来像这样:

class Company < ActiveRecord::Base; end   
class Firm < Company; end  
class Client < Company; end   
class PriorityClient < Client; end

当你执行 Firm.create(:name => “37signals”),这条记录将是 以类型保存在公司表中 =“坚定”。然后,您可以使用 Company.find(:first, "name = '37signals'"),它会返回一个 Firm 对象。

如果您没有类型列 在您的表中定义,单表 不会触发继承。在 这种情况下,它会像平常一样工作 没有特殊魔法的子类 区分它们或 用 find 重新加载正确的类型。

一个很好的教程在这里:http://juixe.com/techknow/index.php/2006/06/03/rails-single-table-inheritance/

【讨论】:

    【解决方案2】:

    型号:

    class Animal < ActiveRecord::Base; end
    class Dog < Animal; end
    class Cat < Animal; end
    

    迁移:

    class CreateAnimals < ActiveRecord::Migration
      def self.up
        create_table :animals do |t|
          # Other attributes...
          t.string :type
        end
      end
    
      def self.down
        drop_table :animals
      end
    end
    

    【讨论】:

      【解决方案3】:

      ActiveRecord 支持将继承层次结构映射到单个表(Single-table inheritance。表将有一个列type 存储实际类的名称并用于选择其他特定于类的列。

      可以实现多表继承映射,如here 所示,但这种特殊方式不可移植,AFAIK。

      【讨论】:

      【解决方案4】:

      委托类型

      一种特殊的方法是通过Delegated Types - 如果您希望能够对所有动物进行分页,并同时查看猫和狗,那么委托类型特别有用。我也喜欢它,因为你不需要有空列,因为它没有意义,就像单表继承解决方案一样。

      # Schema: entries[ id, created_at, updated_at, animalable_type, animalable_id ]  
      
      class Animal < ApplicationRecord
        delegated_type :animalable, types: %w[ Cat Dog ]
      end
      
      module Animalable
        extend ActiveSupport::Concern
      
        included do
          has_one :animal, as: :animalable, touch: true
        end
      end
      
      # Schema: cats[ id, selfishness_level ]
      class Cat < ApplicationRecord
        include Animalable
      end
      
      # Schema: dogs[ id, favourite_game, wag_tail_level ]
      class Dog < ApplicationRecord
        include Animalable
      end
      

      【讨论】:

        猜你喜欢
        • 2011-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多