Ruby on rails 多少课太多了?钢轨STI
我正在开发一个非常大的Rails应用程序。我们最初并没有使用太多的继承,但我们从一位顾问那里获得了一些令人大开眼界的经验,并希望重构我们的一些模型 我们的应用程序中有很多以下模式:Ruby on rails 多少课太多了?钢轨STI,ruby-on-rails,ruby,inheritance,single-table-inheritance,sti,Ruby On Rails,Ruby,Inheritance,Single Table Inheritance,Sti,我正在开发一个非常大的Rails应用程序。我们最初并没有使用太多的继承,但我们从一位顾问那里获得了一些令人大开眼界的经验,并希望重构我们的一些模型 我们的应用程序中有很多以下模式: class Project < ActiveRecord::Base has_many :graph_settings end class GraphType < ActiveRecord::Base has_many :graph_settings #graph type specific
class Project < ActiveRecord::Base
has_many :graph_settings
end
class GraphType < ActiveRecord::Base
has_many :graph_settings
#graph type specific settings (units, labels, etc) stored in DB and very infrequently updated.
end
class GraphSetting < ActiveRecord::Base
belongs_to :graph_type
belongs_to :project
# Project implementation of graph type specific settings (y_min, y_max) also stored in db.
end
class项目
这也会在视图、帮助程序和图形设置模型本身中产生大量条件。这些都不好
一个简单的重构,我们摆脱了GraphType,转而使用更像这样的结构:
class Graph < ActiveRecord::Base
belongs_to :project
# Generic methods and settings
end
class SpecificGraph < Graph
# Default methods and settings hard coded
# Project implementation specific details stored in db.
end
类图谢谢你的智慧,我会回答任何问题。如果差异只是在课堂行为上,那么我认为这不应该是一个问题,这是一个很好的STI候选人。(请注意,我从未用这么多子类尝试过这一点。) 但是,如果您的200个STI类每个都有一些独特的属性,那么您将需要在主表中有大量额外的数据库列,这些列在99.5%的时间内为空。这可能是非常低效的 为了创建类似“多表继承”的东西,我之前成功地做了一些工作,就是使用一点元编程将其他表与每个类特有的细节关联起来:
class SpecificGraph < Graph
include SpecificGraphDetail::MTI
end
class SpecificGraphDetail < ActiveRecord::Base
module MTI
def self.included(base)
base.class_eval do
has_one :specific_graph_detail, :foreign_key => 'graph_id', :dependent => :destroy
delegate :extra_column, :extra_column=, :to => :specific_graph_detail
end
end
end
end
class SpecificGraph'graph\u id',:依赖=>:destroy
委托:额外列,:额外列=,:to=>:特定图表\u详细信息
结束
结束
结束
结束
委托意味着您可以访问关联的详细信息字段,就好像它们直接在模型上一样,而不是通过特定图\u detail
关联,并且出于所有意图和目的,“看起来”这些只是额外的列
您必须在需要连接这些额外细节表的情况下与在主表中只包含额外列的情况之间进行权衡。这将决定是使用STI还是使用关联表的解决方案,如上面的“我的解决方案”。谢谢您的回复。在这一点上,我不认为数据库中会有很多(如果有的话)空值,因为属性是相同的,只是值和方法会改变。(例如,它如何返回要绘制的图形的数据)。如果我们最终使用空字段(可能不是这个实例,而是其他类似的实例),我一定会记住这一点