在Rails中处理“类型”的正确方法是什么?

时间:2009-12-05 17:35:09

标签: ruby-on-rails database-design

对不起,如果之前已经问过这个问题,我搜索过但不确定我正在寻找的正确名称。

我几乎是一个新的轨道和开发新手,我做了一些hacky编程,但我不会说我知道我在做什么。我总是对如何在我的Rails模型和数据库中定义“类型”感到茫然。

例如,假设我有一个模型“Car”并且它具有“Color”属性,其中Color是从已知集合中选择的,而不是RGB值或其他。有东西告诉我应该有另一个表(和相关模型)的颜色,然后在两者之间有某种关系,但哪种关系是合适的?汽车并不属于它的颜色,反之亦然。

当然我可以存储一个整数并在代码中查找,但这对我来说是错误的。

我错过了什么? :)

4 个答案:

答案 0 :(得分:0)

汽车只有1种颜色,因此您可以说Car实例belongs_toColor。你的第二个想法就是将颜色存储为数字并将这些颜色定义为常量,这可能更明智......只要你不需要在应用程序中添加/删除/编辑颜色(换句话说,'住')。

答案 1 :(得分:0)

我对Ruby中类型的体验是,不必考虑 的内容,而是要考虑做什么。在这方面它非常jQuery,不要问用户使用什么浏览器,因为他们的浏览器是否可以做我们需要它做的某些事情。

我知道这不是你问题的主要内容,但考虑到标题和我自己学习Ruby并处理鸭子打字的经验,这似乎是一个恰当的比喻。

你回答,你真正想要定义像颜色这样的新对象的唯一时间就是你要让客户定义的东西。在汽车的情况下,这可能是完全有效的,许多汽车只有一定的颜色,他们有非常特殊的颜色。所以确实有一种颜色有很多车,而一辆车就属于这种颜色。

命名对我来说总是有些奇怪,我刚刚学到的方法是belongs_to是具有id号的模型。它有其原因,但记住这一事实要比每次试图解开逻辑更容易。这就是你必须要保持直线,你会做得很好。 :)

答案 2 :(得分:0)

对于这个例子,我不认为将汽车的颜色存储在单独的模型中是合适的。颜色是汽车的属性,因此汽车表中的列是解决方案。

如果要将颜色选择限制为有限列表,可以使用验证

class Car < ActiveRecord::Base
  validates_inclusion_of :colour, :in => %w( red orange yellow green blue indigo violet )
end

如果这对您的用例来说过于简单,我建议您查看ActiveRecord::Aggregations::ClassMethods.composed_of。我认为ActiveRecord模型不是解决方案。

答案 3 :(得分:0)

颜色可能是一个复杂的对象,也可能是一个非常简单的对象,具体取决于您的需要。

  • 简单:随后将整数转换为任何其他格式,或存储在字符串中的十六进制值,如“a3ab34”。
  • 复杂:您想要将颜色映射到某些人物标题。

为简单起见,您只需在名为color的汽车中添加一列,并覆盖读取器方法以返回您想要的任何颜色格式,如此。

class Car < ActiveRecord::Base
  def color(format = :integer)
     case format
     when :integer: super
     when :hex: # ... hex conversion code
     # ... more conditions ...
     end
  end
end

如果我们谈论复杂的案例,那就不一样了。然后,您应该有一个名为Color的单独模型。然后Car belongs_to :color就像上面说的那样。Car has_one :color。说car_id在语义上更正确,但是你强迫颜色表存储color_id,这将是一种倒退。在我们的例子中,Car将存储color_id。因此,请务必进行迁移,将cars添加到表colors

然后,您应该为id表创建迁移,例如,包括titlecode和{{1}},以及您必须预先填充的内容你自己用铁路播种的东西。 (见http://railscasts.com/episodes/179-seed-data