【发布时间】:2020-07-03 22:05:32
【问题描述】:
我正在努力在一个班级中使用枚举来制作我的目录,来自这个教程:https://naturaily.com/blog/ruby-on-rails-enum。
我的模型:
**app/models/catalog.rb**
class Catalog < ApplicationRecord
include ArrayToEnumHash
enum state: array_to_enum_hash(CatalogState::STATES)
def state
@state ||= CatalogState.new(read_attribute(:state))
end
end
**app/models/catalog_state.rb**
class CatalogState
STATES = %w(incoming in_progress finished).freeze
def initialize(state)
@state = state
end
# what you need here
end
**app/concerns/array_to_enum_hash.rb**
module ArrayToEnumHash
extend ActiveSupport::Concern
def array_to_enum_hash(array)
result = {}
v = array.to_enum
w = array.map {|v| v.to_sym }.to_enum
loop do
result[w.next] = v.next
end
result
end
end
**db/schema.rb**
create_enum :catalog_state, [
"incoming",
"in_progress",
"finished",
]
create_table "catalogs", force: :cascade do |t|
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.enum "state", enum_name: "catalog_state"
t.index ["state"], name: "index_catalogs_on_state"
end
我的目录看起来不错:
#<Catalog:0x00007fe87dbfb810
id: 3,
created_at: Thu, 02 Jul 2020 16:52:36 UTC +00:00,
updated_at: Fri, 03 Jul 2020 19:51:26 UTC +00:00,
status: "unset",
auction_type: "internet",
state: "in_progress">
但是,在我的控制台上,ActiveRecord 不会构建枚举快捷方式:
[5] pry(main)> c.state
=> "in_progress"
[6] pry(main)> c.in_progress?
NoMethodError: undefined method `in_progress?' for #<Catalog:0x00007fe87dbfb810>
from /Users/pierre/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activemodel-6.0.3.2/lib/active_model/attribute_methods.rb:432:in `method_missing'
WTF?
【问题讨论】:
-
我一定要问
create_enum和t.enum是从哪里来的? -
我的目标是创建直接访问方法。比整数和数组设置更进一步:我设置了哈希 {:incoming=>"incoming", :in_progress=>"in_progress", 而不是数组 ["incoming", "in_progress", "finished"] :finished=>"finished"},这样我就可以直接访问:
my_instance.incoming? => false,my_instance.incoming!。所以问题是关于辅助设置的,这似乎是正确的但不起作用。 -
但是你不需要自己做。这是由 Rails 处理的:D,看看docs; “... bang 和谓词方法以及相关的范围现在相应地添加了前缀和/或后缀”。
-
如果您要赋予该枚举列的用途需要 ActiveRecord 无法提供的东西,您可以使用 gem。否则,我在答案中给出的例子必须足够开始了。
-
无论如何你都可以,它不直接附加到gem的使用上。不过,我必须提到,如果您要对所有这些“voivodeship”进行硬编码,为什么不将它们存储在您的数据库中呢?这种方法可能有优点,但也有缺点。值得深思。
标签: enums rails-activerecord helper ruby-on-rails-6