在Rails中,在模型中存储多个布尔属性的最佳方法是什么?

San*_*jay 16 ruby-on-rails

我有一个模型House,有许多布尔属性,如has_fireplace,has_basement,has_garage,等. House有大约30个这样的布尔属性.构建此模型以实现高效数据库存储和搜索的最佳方法是什么?

我想最终搜索所有Houses有壁炉和车库的东西.

我想,天真的方法是在模型中简单地添加30个布尔属性,每个属性对应于数据库中的一列,但我很好奇是否有一个我不知道的Rails最佳实践.

Jos*_*hua 16

您的"天真"假设是正确的 - 从查询速度和生产率角度来看,最有效的方法是为每个标志添加一列.

你可能会像其他人所描述的那样获得幻想,但除非你解决一些非常具体的性能问题,否则不值得努力.您最终会得到一个难以维护,灵活性降低且开发时间更长的系统.

  • 同意.如果你愿意,将所有布尔值放在属于房屋的单独模型中可能更整洁,比如房子has_one:feature_set(或其他),并且功能集包含所有布尔值.然后你可以使用虚拟属性来获取一些糖,比如House model def has_fireplace?self.feature_set.fireplace; 结束 (2认同)

bjg*_*bjg 7

对于单个模型中的许多布尔值,您可以考虑使用单个整数和按位运算来表示,存储和检索值.例如:

class Model < ActveRecord::Base
  HAS_FIREPLACE = (1 << 0)
  HAS_BASEMENT  = (1 << 1)
  HAS_GARAGE    = (1 << 2)

  ...
end
Run Code Online (Sandbox Code Playgroud)

然后调用一些模型属性,flags如下所示:

flags |= HAS_FIREPLACE
flags |= (HAS_BASEMENT | HAS_GARAGE)
Run Code Online (Sandbox Code Playgroud)

并测试如下:

flags & HAS_FIREPLACE
flags & (HAS_BASEMENT | HAS_GARAGE)
Run Code Online (Sandbox Code Playgroud)

你可以抽象成方法.作为一种实现,应该在时间和空间上非常有效


Rob*_*lík 5

我建议使用flag_shih_tzu宝石.它可以帮助您在一个整数列中存储许多布尔属性.它为每个属性提供了命名范围,并将它们链接在一起作为活动记录关系.