Ruby on Rails ActiveRecord:我应该如何存储对象的状态?
我有一个用户模型,它有一个状态。该状态可以是这些:“未经验证的”,“主动”,“删除”]Ruby on Rails ActiveRecord:我应该如何存储对象的状态?
什么是存储在数据库中的对象的状态的最好方法?
我应该创建三个布尔字段吗?这不会有什么意义,因为我可能想要轻松扩展状态的数量,并且只有一个状态可以同时为“真”。
我应该使用state_machine宝石只为固定值的简单切换?
或有任何其他常见的方式,最好的做法,或者一个简单的宝石这样的工作吗?
一个非常简单的解决方案,我已经使用这个:
在迁移
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
我会将它保留为零,'激活','删除'。如果您希望在切换状态时有额外的进程挂钩,例如发送的电子邮件,那么state_machine gem会很有用。另外,如果您希望有其他分析功能,例如某人从未验证状态变为活动状态,可能会有用'active_on_date',并在转换发生时将其存储为日期时间。
您可以使用一个枚举类型的状态存储为一个简单的整数。我通常使用active_enum宝石来简化。这将是这个样子
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。
请勿使用布尔字段。
如果国家的名字就像一个“钥匙”,并不会改变,你可以将它们存储在数据库中的文本字段。只需使用
add_column :users, :state, :string
添加迁移当您保存对象时,它会采取user.state和符号存储为“未验证”,“活动”等
如果状态是一个字符串可能会在某个时间点重新命名,那么您可以将它们放入自己的表格中,并为它们制作自己的主动记录模型,而不是使用符号。做一个
rails g model State name:string
轨道将创建一个模型文件和他们的迁移。然后用这个改变迁移:
add_column :users, :state_id, :integer
您可以使用未经验证,活跃等直接在SQL或通过种子或现有的迁移填充状态列表。如果需要,您也可以在它们之间创建一个外键。
然后在你的代码,以设置状态,你这样做:
user.state = State.find_by_name(:unverified)
您确定要将'state'列存储为'text'吗?它看起来好像是一个“字符串”。 – jaredonline 2012-03-06 20:49:29
是的,你是对的。我正是这个意思。现在编辑。 – fregas 2012-03-06 21:21:29
我真的很喜欢这个实现,除了ID不会以参照完整性存储在数据库中。 – fregas 2012-03-06 21:40:53
这是一个很好的观点。除了实现一个'''State''模型的解决方案,这是正确的吗? – 2012-03-06 22:08:22