我应该命名STI模型吗?

时间:2013-08-14 07:12:50

标签: ruby-on-rails ruby namespaces sti

我有以下型号:

module Core
  class Conditioner
    include Mongoid::Document

    field :operator, type: String, default: '' # can be !=, ==, <, >, <=, >=, =
  end
end

module Core
  class Count < Conditioner
    field :threshold, type: Integer, default: 0 # a simple threshold
  end
end

module Core
  class Time < Conditioner
    UNITS = %w(seconds minutes hours days weeks months years)

    # will be use like this: Time.value.send(Time.unit) Ex: 3.minutes
    field :value, type: Integer, default: 0    # 3
    field :unit,  type: String,  default: ''   # minutes

    validates :unit,  presence: true, inclusion: { in: UNITS }
  end
end

想知道我是否应该将CountTime类命名为Conditioner?像这样:

module Core
  class Conditioner::Time < Conditioner
  end
end

因为我现在必须像Time.now这样呼叫::Time.now

修改

关于答案,也许这应该是一个更好的主意:

module Core
  module Conditioner
    class Base
    end
  end
end

module Core
  module Conditioner
    class Count < Conditioner::Base
    end
  end
end

module Core
  module Conditioner
    class Time < Conditioner::Base
    end
  end
end

由于定义一个名为Core::Time的类可能过于通用而且没有多大意义。

你怎么看?不确定这里的最佳做法。

3 个答案:

答案 0 :(得分:1)

您不必命名它,尽管如果您愿意,也可以。

您是否应该取决于您想要建模的内容(而不是您是否必须使用:: Time来解决时间......)。看起来你的Core :: Time已经是Core :: Conditioner的子类,所以将它作为它的超类的内部类是没有多大意义的。在您的情况下,最好不要命名它。

与ruby具有相同的类名在这里不是问题,因为您已经使用Core命名它。

答案 1 :(得分:0)

在我看来,不要使用Ruby或Rails使用的类名,这可能是个问题。无论何时使用它都必须小心。我觉得没必要。除非要维护许多模型,否则不要使用名称空间。保持简单,维护将更容易:)

答案 2 :(得分:0)

通过将Conditioner添加到Time前缀,您唯一要做的就是Core模块的常量查找在查找{{1}时将看不到您的Conditioner::Time类}}。所有其他类(TimeCount)仍然认为Conditioner正在取代Conditioner::Time

Time

module Core def time Time.now end class Conditioner def time Time.now end end end module Core class Count < Conditioner def time Time.now end end end module Core class Conditioner::Time < Conditioner def time Time.now end end end 之类的任何通话都会失败,但

Core::Count.new.time

class A include Core end 将显示当前时间,而在这种情况下:

A.new.time

module Core def time Time.now end class Conditioner def time Time.now end end end module Core class Count < Conditioner def time Time.now end end end module Core class Time < Conditioner def time Time.now end end end class A include Core end 也会失败。现在,原因很简单:常量查找总是查看当前命名空间中可用的常量(A.new.time),然后在查找{{1}的命名空间之前爬上当前命名空间的祖先链。 }(Core也可以被称为Object。它不会搜索子命名空间(你通过Time之前放置Object::Time创建),这就是重命名的原因您的班级Conditioner::Time仅更改Time模块的查找,但不会更改Conditioner::Time中的班级。

因此,在这种情况下要求采取最佳做法:只需将其留给您调用您的班级Core并通过Core引用Time。这是一个众所周知的做法,额外的命名空间避免使用它的好处是微不足道的。