在轨道模型中使用ENUM时,这是一段了不起的代码
STATUS = { approval: 0,
rejected: 1,
idle: 2,
}
def status
STATUS.key(read_attribute(:status))
end
def status=(s)
write_attribute(:status, STATUS[s])
end
当我将它粘贴到任何模型中时,效果很好,这正是问题所在。我使用它很多次,所以我想保持代码干。
我尝试将其复制到application_helper.rb
,但它不起作用。什么是使其工作而不重复所有其他模型的最佳方法
答案 0 :(得分:1)
该代码可以抽象为模块。
# lib/enumable.rb
module Enumable
extend ActiveSupport::Concern
module ClassMethods
def enum(name, options)
map = Hash[options.each_with_index.map { |e, i| [e, i] }]
const_set(name.to_s.pluralize.upcase, map)
define_method name do
map.key(read_attribute(name))
end
define_method "#{name}=" do |value|
write_attribute(name, map[value])
end
end
end
end
默认情况下,Rails不会从lib
自动加载。将其添加到应用程序配置。
# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
将新模块包含在模型中。
# app/models/project.rb
class Project < ActiveRecord::Base
include Enumable
enum :status, [:approval, :rejected, :idle]
end
$ rails c
Loading development environment (Rails 3.2.9)
1.9.3-p327 :001 > project = Project.new
=> #<Project id: nil, status: nil, created_at: nil, updated_at: nil>
1.9.3-p327 :002 > project.status = :rejected
=> :rejected
1.9.3-p327 :003 > project.status
=> :rejected
1.9.3-p327 :004 > Project::STATUSES
=> {:approval=>0, :rejected=>1, :idle=>2}