将整数值列转换为字符串表示的最佳实践

时间:2008-12-22 10:35:57

标签: ruby-on-rails

假设您有类似以下的模型:

class Stock < ActiveRecord::Base
  # Positions
  BUY = 1
  SELL = 2
end

在该类中,作为整数类型的属性称为“位置”,可以包含任何上述值。将这些整数值转换为人类可读字符串的Rails最佳实践是什么?

a)使用辅助方法,但是你必须确保让辅助方法和模型保持同步

def stock_position_to_s(position)
  case position
  when Stock::BUY
    'buy'
  when Stock::SELL
    'sell'
  end
  ''
end

b)在模型中创建一个方法,这种方法打破了干净的MVC方法。

class Stock < ActiveRecord::Base
  def position_as_string
    ...snip
  end
end

c)在Rails 2.2中使用新的I18N内容的新方法?

只是好奇其他人在数据库中有一个需要输出为用户友好字符串的整数列时正在做什么。

谢谢, 肯尼

7 个答案:

答案 0 :(得分:3)

听起来像是一个属于视图的东西,因为它是一个演示问题。

如果它被广泛使用,那么在用于DRY目的的辅助方法中,如果需要则使用I18N。

答案 1 :(得分:1)

试试这样的东西

class Stock < ActiveRecord::Base
  @@positions => {"Buy" => 1, "Sell" => 2}
  cattr_reader :positions

  validates_inclusion_of :position,  :in => positions.values
end

它允许您将位置保存为整数,以及轻松使用选择助手。

当然,观点仍然是一个问题。您可能希望使用帮助程序或为此目的创建position_name方法

class Stock < ActiveRecord::Base
  @@positions => {"Buy" => 1, "Sell" => 2}
  cattr_reader :positions

  validates_inclusion_of :position,  :in => positions.values

  def position_name
    positions.index(position)
  end
end

答案 2 :(得分:0)

是否有充分的理由让应用程序以编程方式将整数转换为人类可读的字符串?

我会创建具有位置整数属性和名称属性的位置对象。

然后你可以做

stock.position.name

答案 3 :(得分:0)

@HermanD:我认为将值存储在整数列而不是字符串列中要好得多,原因有很多。

  1. 它节省了数据库空间。
  2. 比字符串更容易/更快地索引整数。
  3. 您不难将人类可读的字符串编码为数据库中的值。 (如果客户说“购买”应该变成“购买”,会发生什么?现在,UI显示“购买”,但您需要在数据库中设置“购买”。)
  4. 因此,如果您将某些值作为整数存储在数据库中,那么在某些时候,您将需要将它们作为字符串显示给用户,并且我认为您可以以编程方式执行此操作的唯一方法。

    您可以将此信息移动到另一个对象,但是,恕我直言,我会说这是矫枉过正。然后,您必须添加另一个数据库表。添加另一个“管理员”部分,用于添加,删除和重命名这些值,依此类推。更不用说如果您有多个列,在需要此行为的不同模型中,您要么必须创建大量这些对象(例如:stock_positions,stock_actions,transaction_kinds等等),或者您必须设计它通常足以使用多态关联。最后,如果位置名称是硬编码的,那么您将无法在以后轻松将其本地化。

    @frankodwyer:我不得不同意使用辅助方法可能是最好的方法。我希望他们可能是一个“光滑”的方式来做到这一点,但它看起来不像。现在,我认为最好的方法是创建一个新的辅助模块,可能类似于StringsHelper,并在其中填充一堆方法,用于将模型常量转换为字符串。这样我可以使用帮助器中的所有I18N内容来提取本地化的字符串,如果我将来需要的话。令人讨厌的部分是,如果有人需要向模型列添加新值,那么他们还必须在帮助器中添加一个检查。不是100%干,但我猜“足够接近”......

    感谢你们两位的投入。

    肯尼

答案 4 :(得分:0)

为什么不使用本机数据结构的属性?例如:

类库存&lt;的ActiveRecord :: Base的  ACTIONS = [nil,'buy','sell'] 端

然后你可以使用Stock :: ACTIONS [1]#=&gt;抓住它们'买'或股票::行动[2]#=&gt; '卖出'

或者,您可以使用哈希{:buy =&gt; 1,:sell =&gt; 2}并以Stock :: ACTIONS [:buy]#=&gt;的形式访问它1

你明白了。

答案 5 :(得分:0)

@Derek P.这是我第一次使用的实现,虽然它肯定有效,但它有点打破MVC隐喻,因为模型现在在其类中定义了与视图相关的信息。控制器中的字符串是一回事,但模型中的字符串(在我看来)绝对违背了清洁MVC的精神。

如果你想开始本地化,它也没有用,所以虽然这是我最初使用的方法,但我认为这不是未来发展的方法(绝对不是在I18N世界。)

感谢您提供的意见。

此致 肯尼

答案 6 :(得分:0)

我写了一个可能有点帮助的插件。见this。它允许您定义列表并为您提供以_str结尾的漂亮方法以用于显示目的。