1

在 Rails 模型中使用 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但它不起作用。什么是让它工作而不在所有其他模型中重复的最佳方法

代码信用:http ://www.kensodev.com/tag/enum/

4

1 回答 1

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} 
于 2012-12-23T18:30:58.440 回答