2

我是 Ruby 和 Rails 的新手(和编程!),并试图找出将属性从模型传递给它的 STI 子代的惯用方式。

我有一个通用模型“文档”,以及一些从它继承的模型——让我们以“教程”为例。我有一个“图标”的字符串字段,我想在其中存储图标的文件名而不是完整路径(我认为路径应该取决于每个模型,因为它是检索记录数据的细节?):

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

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

4

2 回答 2

4

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

现在是安置问题:

在班上

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

# document.rb
#
class Document < ActiveRecord::Base
  attr_accessible :title, :body, :icon

  ASSET_DOMAIN = "http://assets.example.com/"

end

这将可以在Document Tutorial从这些对象继承的其他对象中访问。

环境.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

这可能是社论,但红宝石学家在看到@@. 有时间和地点,但对于你想做的事情,我会使用一个常数并决定你需要把它放在哪里。

于 2012-05-03T20:52:10.887 回答
1

您可以简单地从in覆盖该icon函数(因为它继承自它)并让它返回正确的路径。DocumentTutorial

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

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可以重新定义方法以给出所需的输出。ASSET_DOMAIN在这种情况下,将很少变化的值存储在常量中也是明智的。

于 2012-05-03T20:44:09.827 回答