STI,MTI还是CTI,这是目前建议的Rails 4解决方案?

use*_*489 6 postgresql inheritance ruby-on-rails sti ruby-on-rails-4

我有一个基本的events表格,并希望有子表为每个事件类型(hiking,party,riverrun等).

我看到很多关于CTI,MTI和STI的旧帖子(2011/2012).一些解决方案适用于Heroku,而其他解决方案则没有.

什么是"当前"Rails做这种事情的方式?是否已将其添加到Rails 4.x中?是否有一个神奇的宝石处理这个(与Heroku上的Postgres)?

一些信息,如果它有帮助:

将来,将有20-50个事件,每个子表可能多达80列.该网站托管在Heroku上.运行Rails 4.0.2

Tim*_*mer 0

STI - 单表继承正是您所寻找的。 http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Single+table+inheritance http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html

您一如既往地创建模型,但将属性even_type作为字符串添加到数据库中。(默认为“type”)您让 EventModel 知道这将是继承列。

class Event < ActiveRecord::Base
    self.inheritance_column = :event_type 
    # dont forget your scopes to easy access them by type
    # Event.party or Event.ultrafestival
    scope :party, -> { where(event_type: 'Party') }
    scope :ultrafestival, -> { where(event_type: 'UltraFestival') }
    scope :tomorrowland, -> { where(event_type: 'TomorrowLand') }


    def host
      raise "needs to be implemented in your sub-class!"
    end

end
Run Code Online (Sandbox Code Playgroud)

比你创建一些子类。确保它们继承自Event

class Party < Event
end

class UltraFestival < Event
end

class Tomorrowland < Event
end
Run Code Online (Sandbox Code Playgroud)

基本上,所有对象都是事件!所以,如果你去的话,Event.all你就会得到它们!从技术上讲,对象可以是其他东西。所有这些“事件”将存储在同一个表中,它们将因event_type本例中的“party”、“ultra_festival”或“tomorrowland”而有所不同。

现在您可以向每个类添加一些特殊的东西,例如

 class Party < Event
     def host
       "private homeparty PTY"
     end

     def publish_photostream 
     end

     def call_a_cleaning_woman
     end
 end

class UltraFestival < Event
   attr_accessor :location

   def host
     "UMF Festival Corp."
   end

   def is_in_europe?        
   end     

   def is_in_asia?        
   end     
end

class Tomorrowland < Event

    def host
      "ID&T"
    end

    def download_after_movie!
    end

end
Run Code Online (Sandbox Code Playgroud)

这是多年来的标准 Rails 方式。当然,它适用于每个主机和 postgres。

// 编辑:如果你的子事件需要数据库中的一些特殊表,那么你需要使用MTI,多表继承。