新手问题 Rails Model 枚举类型方法重定义

excosy · 2016年04月21日 · 最后由 bastengao 回复于 2016年04月28日 · 2780 次阅读

在 rails model 里不免有些数据字段仅能取若干个离散的非数字值,这种情况的通用解决方案是在 model 里定义 tinyint 字段然后在 model 里添加这个属性的注释。比如一个商品 Deal 的状态可能有如下几种: ['审核中', '销售中', '未开始', '已结束', '已卖光', '已下架'] 那么可以定义:

t.integer :status, limit: 1, null: false, default: 0

然后在 model 里为这个字段注释:

STATUS = ['审核中', '销售中', '未开始', '已结束', '已卖光', '已下架']

取值则为

deal = Deal.new
Deal::STATUS[deal.status]

现在我的问题是,能不能在 concern 里定义一个可复用的方法,在实现之后 deal 有 enum_status 方法,使 class Deal extend Concern 后,deal.enum_status 能直接输出“审核中”而不是 0? 以下是初步想法:

def show_enum_columns
  self.column_names.each do |x|
    begin
      column = self.const_get x.upcase! if self.send(x).is_a? Integer
      self.define_method "enum_#{x}" do                      # 1
        self.class.const_get(x.upcase!)[self.send(attr)]     # 2
      end if column.present?
    rescue NameError
      next
    end
  end
end

这里有两个问题:1. define_method 是私有方法;2. 这里的 self 需要指代 Deal.new,事实上这里是 Deal.new 还是 Deal?3. 这个方法需要在 extend 之后手动执行 Deal.show_enum_columns 生成方法,有没有办法使其自动在 extend 时就生成实例方法 enum_status?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号