我是Ruby和Rails(以及编程!)的新手,并试图找出将属性从模型传递给其STI子代的惯用方法。
我有一个通用模型'Document',以及一些继承它的模型 - 让我们以'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'的最佳方法是什么?我不认为我应该使用实例变量,因为值不需要更改每个模型实例。任何想法都非常赞赏(即使这意味着重新考虑它!)
答案 0 :(得分:3)
看起来您正在尝试创建一个可以重用以构建路径的常量值。我不使用类变量,而是使用常量。
现在问题是:
如果它真的只需要在Document
和从它继承的类中使用,请在堆栈顶部定义一个常量:
# document.rb
#
class Document < ActiveRecord::Base
attr_accessible :title, :body, :icon
ASSET_DOMAIN = "http://assets.example.com/"
end
可以在Document
Tutorial
和其他继承的对象中访问此内容。
如果这是一个值,您将使用无处不在,那么为environment.rb
添加常量呢?这样你就不必记得在你放置它的所有类中重新定义它。
# environment.rb
#
# other config info
#
ASSET_DOMAIN = "http://assets.example.com/"
然后你可以在任何你喜欢的地方建立链接,而不受Class的限制:
# 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似乎感到畏缩。有时间和地点,但是对于你想做的事情,我会使用常数并决定你需要放置它的位置。
答案 1 :(得分:0)
您可以简单地覆盖icon
中Document
的{{1}}函数(因为它继承自它)并让它返回正确的路径。
这是面向对象编程中Polymorphism的经典案例。一个例子:
Tutorial
输出:
class Document
attr_accessor :title, :body, :icon
ASSET_DOMAIN = "http://assets.example.com/"
def icon
return ASSET_DOMAIN + "documents/" + "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://assets.example.com/documents/document_icon.png
http://assets.example.com/tutorials/tutorial_icon.png
是Tutorial
的子类,它会继承其字段及其方法。因此,Document
,:title
和:body
不需要在:icon
内重新定义,Tutorial
方法可以重新定义以提供所需的输出。在这种情况下,存储一个很少会在常量icon
中更改的值也是明智的。