此问题基于以下问题:Rails find_or_create_by with/without where
我遇到了一些关于enum
&的奇怪问题。 rails中的find_or_initialize_by
方法。
假设我有模型Task
。
class Task < AR::Base
enum status: { todo: 0, awaiting: 1, done: 2, another_one: 3, et.c. }
我希望通过todo
和awaiting
任务查找,如果不存在,请创建一个新任务,但没有todo
和awaiting
值(状态)应该只是零)。但是,ActiveRecord::Enum
在这里罢工!
在大多数情况下,这是正常的代码:
Task.where(status: [Task.statuses[:todo], Task.statuses[:awaiting]]).find_or_initialize_by(title: 'epic')
但由于this字符串,我感到烦恼'[0, 1]' is not a valid status
异常。如果没有多余的代码,我该如何避免这种异常呢?
答案 0 :(得分:0)
查询枚举属性时,应使用the symbol representing the enum而不是实际的整数列值:
@task = Task.where(status: [:todo, :awaiting])
.find_or_initialize_by(title: 'epic')
因此,'[0, 1]' is not a valid status
因为Rails试图提供帮助并为您查找枚举值。通常,除非您正在构建自定义SQL字符串,否则几乎不需要使用实际的整数值:
Task.where.not(status: :awaiting)
Rails还根据枚举生成范围:
@tasks = Task.todo.awaiting.find_or_initialize_by(title: 'epic')
# or
@tasks = Task.todo.merge(Task.awaiting)
.find_or_initialize_by(title: 'epic')
答案 1 :(得分:0)
现在我看到一个相对较酷的解决方案。如果有人能更好地提供解决方案,那将会很棒。
gem 'active_record_union'
使用它!
Task.todo.union(Task.awaiting).union(Task.starting)