如何在 Ruby on Rails 中实现 Active Record 继承?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1598936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:52:48  来源:igfitidea点击:

How to implement Active Record inheritance in Ruby on Rails?

ruby-on-railsdatabaseinheritanceactiverecordmodel

提问by andrisetiawan

How to implement inheritance with active records?

如何使用活动记录实现继承?

For example, I want a class Animal, class Dog, and class Cat.

例如,我想要一个类 Animal、类 Dog 和类 Cat。

How would the model and the database table mapping be?

模型和数据库表的映射是怎样的?

回答by Toby Hede

Rails supports Single Table Inheritance.

Rails 支持单表继承。

From the AR docs:

AR 文档

Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:

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

When you do Firm.create(:name => "37signals"), this record will be saved in the companies table with type = "Firm". You can then fetch this row again using Company.find(:first, "name = ‘37signals'") and it will return a Firm object.

If you don‘t have a type column defined in your table, single-table inheritance won‘t be triggered. In that case, it‘ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.

Active Record 通过将类的名称存储在默认名为“type”的列中来允许继承(可以通过覆盖 Base.inheritance_column 来更改)。这意味着继承看起来像这样:

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

当您执行 Firm.create(:name => "37signals") 时,此记录将保存在公司表中,类型为 = "Firm"。然后您可以使用 Company.find(:first, "name = '37signals'") 再次获取该行,它将返回一个 Firm 对象。

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

A pretty good tutorial is here: http://juixe.com/techknow/index.php/2006/06/03/rails-single-table-inheritance/

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

回答by PreciousBodilyFluids

Models:

楷模:

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

Migration:

移民:

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

回答by elder_george

ActiveRecord supports mapping inheritance hierarchies to a single table(Single-table inheritance. Table would have a column typewhich stores name of actual class and is used to select other class-specific columns.

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

It is possible to implement multi-table inheritance mapping, as shown here, but this particular way is not portable, AFAIK.

它可以实现多表继承映射,如图所示这里,但这种特别的方式是不可移植的,据我所知。