声明Rails模型子类的静态属性

我是Ruby和Rails(以及编程!)的新手,并且试图找出将属性从模型传递给其STI子元素的惯用方法。

我有一个通用模型’Document’,以及一些inheritance它的模型 – 让我们以’Tutorial’为例。 我有一个’icon’的字符串字段,我想在其中存储图标的文件名但不是完整路径(我认为路径应该取决于每个模型,因为它是检索记录数据的细节?):

class Document < ActiveRecord::Base attr_accessible :title, :body, :icon @@asset_domain = "http://assets.example.com/" @@asset_path = "documents/" def icon @@asset_domain.to_s + @@asset_path.to_s + read_attribute(:icon).to_s end end 

这是我想对子类做的事情,所以他们在适当的地方寻找他们的’图标’(或任何其他资产)。

 class Tutorial < Document attr_accessible :title, :body, :icon @@asset_path = "tutorials/" # Other tutorial-only stuff end 

我已经阅读过关于类变量的内容,并理解为什么我上面写的内容并没有像我预期的那样工作,但是在Tutorial类中覆盖’asset_path’的最佳方法是什么? 我不认为我应该使用实例变量,因为值不需要更改每个模型实例。 任何想法都非常赞赏(即使这意味着重新考虑它!)

看起来您正在尝试创建一个可以重用以构建路径的常量值。 我不使用类变量,而是使用常量。

现在的问题是:

在class上

如果它真的只需要在Document和从它inheritance的类中使用,请在堆栈顶部定义一个常量:

 # document.rb # class Document < ActiveRecord::Base attr_accessible :title, :body, :icon ASSET_DOMAIN = "http://assets.example.com/" end 

这可以在Document Tutorial和其他inheritance的对象中访问。

的environment.rb

如果这是一个你将在任何地方使用的值,那么为你的environment.rb添加一个常量呢? 这样您就不必记住在放置它的所有类中重新定义它。

 # environment.rb # # other config info # ASSET_DOMAIN = "http://assets.example.com/" 

然后你可以在任何你喜欢的地方建立链接而不受类的限制:

 # documents.rb # icon_path = ASSET_DOMAIN + path_and_file # tutorial.rb # icon_path = ASSET_DOMAIN + path_and_file # non_document_model.rb # icon_path = ASSET_DOMAIN + path_and_file 

这可能是编辑,但是当他们看到@@时,rubyists似乎很畏缩。 有时间和地点,但对于你想要做的事情,我会使用常数并决定你需要放置它的位置。

您可以简单地覆盖Tutorial Document中的iconfunction(因为它inheritance了它)并让它返回正确的路径。

这是面向对象编程中多态性的经典案例。 一个例子:

 class Document attr_accessor :title, :body, :icon ASSET_DOMAIN = "http://sofzh.miximages.com/ruby-on-rails/ + document_icon.png" end end class Tutorial < Document def icon return ASSET_DOMAIN + "tutorials/" + "tutorial_icon.png" end end d = Document.new puts d.icon i = Tutorial.new puts i.icon 

输出:

 http://sofzh.miximages.com/ruby-on-rails/document_icon.png http://sofzh.miximages.com/ruby-on-rails/tutorial_icon.png 

请注意,因为TutorialDocument子类 ,它inheritance了它的字段和方法。 因此:title:body:icon不需要在Tutorial重新定义,可以重新定义icon方法以提供所需的输出。 在这种情况下,存储一个很少会在常量ASSET_DOMAIN中更改的值也是明智的。