我有一个用户模型,它有一个状态。州可以是以下任何一种:['未经验证','有效','已删除']
在数据库中存储对象状态的最佳方法是什么?
我应该创建三个布尔字段吗?这没有多大意义,因为我可能想要轻松扩展状态数量,同时只有一个状态可以是“真实”。
我是否应该仅使用state_machine gem来简单地切换常量值?
或者,对于这种工作,还有其他常用的方法,最佳实践或简单的宝石吗?
答案 0 :(得分:17)
我用过的一个非常简单的解决方案:
在您的迁移中
add_column :users, :state, :string
在你的模特中
class User < ActiveRecord::Base
STATES = %w{ unverified active deleted }
STATES.each do |state|
define_method("#{state}?") do
self.state == state
end
define_method("#{state}!") do
self.update_attribute(:state, state)
end
end
end
然后你可以打电话
@user.active? # => returns true/false
或者
@user.active! # => sets the users state to active
答案 1 :(得分:3)
如果您将Rails3与MySQL数据库一起使用您可以使用enum_column。它提供了:enum
列何时用于迁移以及验证方法。它还提供了一个enum_select视图助手。
答案 2 :(得分:1)
我会把它留作零,'主动','删除'。如果你想在切换状态时有额外的进程挂钩,就像发送的电子邮件一样,那么state_machine gem就会很有用。此外,如果您想要进行其他分析,例如当某人从未验证状态变为活动状态时,可能有必要使用“active_on_date”并将其存储为转换发生时的日期时间。
答案 3 :(得分:1)
您可以使用枚举类型将状态存储为简单整数。我通常使用active_enum gem来实现这一点。它看起来像这样
class User
# An enumerated type representing the current state of the user
enumerate :state do
value name: "unverified"
value name: "active"
value name: "deleted"
end
end
这将允许您以下列方式检查状态
# check if active
user.state?(:active)
只需确保state
表中有一个名为User
的整数字段(或任何您想要调用的枚举类型)。
有关详细信息,请参阅gem documentation。
答案 4 :(得分:1)
不要使用布尔字段。
如果状态名称类似于“键”并且不太可能更改,则可以将它们作为文本字段存储在数据库中。只需使用
添加迁移add_column :users, :state, :string
保存对象时,将使用user.state并将符号存储为“未验证”,“活动”等字符串。
如果某些状态可能会在某个时候被重命名,那么您可以将它们放入自己的表中并为它们创建自己的activerecord模型,而不是使用符号。做一个
rails g model State name:string
rails将为它们创建模型文件和迁移。然后用这个改变迁移:
add_column :users, :state_id, :integer
您可以直接在sql中或通过种子或现有迁移来填充未验证,活动等的状态列表。如果需要,您还可以在它们之间创建外键。
然后在你的代码中,要设置状态,你可以使用它:
user.state = State.find_by_name(:unverified)