`

ror中属性值存储的处理

    博客分类:
  • ruby
阅读更多
今天细看了quakewang的那篇文章,获益匪浅,写得真是太好了.
http://www.iteye.com/topic/448235
其实这篇文章已经写得非常的详细了,没有什么可写的。
但是为了缅怀一下,决定还是写一下,由于本人对ROR的学习时间并不长,只一个月左右,不管对ruby还是rails的理解都很有限,下面再介绍一下其过程。

在java中经常遇见数据库存储属性对应的值,而页面显示相应的名称。如['男', 0], ['女', 1]。数据库存储0或1,而页面显示男或女。处理的时候也有两种处理方式,一种是建立一个常量的类,通过Map来实现存取的常量。第二种是使用hibernate的特性,有个属性专门用来代替数据库某值存取,如把0替换成男,至于那个属性叫什么现在记不清了。

今天看了一下牛人在ror上实现方式,非常的不错,所以决定把详细过程再写一下。

一、首先解决数据库字段,建立一个迁移:



二、实现一个插件,虽然没有在书上看见过这方面的介绍,但其实很简单。


上面这张图是插件的目录结构。
首先看一下enum_attr.rb:

module EnumAttr
  module Mixin
    def enum_attr(attr, enums)
      #将attr转换成字符串对象,不然下面就不能使用upcase方法
      attr = attr.to_s
      self.class_eval(%Q{
       ENUMS_#{attr.upcase} = enums
       validates_inclusion_of attr, :in => enums.map{|e| e[1]}, :allow_nil => true
       def #{attr}_name
       #ENUMS_#{attr.upcase}是一个数组,数据来自model类常量,而#{attr}是model类属性的值,这两个attr是不一样的,这个方法主要用在显示记录的地方。也就是说,数据库已经存在这条记录,只是根据这个值找到相应的键。如在[['男', 0], ['女', 1]]中,数据库存储的是0或1,如果属性值是0,将返回'男'。
       ENUMS_#{attr.upcase}.find{|option| option[1] == #{attr}}[0] unless #{attr}.nil?
       end
        })
    end
  end
end

这段代码写得非常的精髓,要理解每一个细节还是得花点时间的,主要作用是在model类中建立ENUMS_#{attr.upcase}方法(用于遍历)、验证字段、#{attr}_name方法(用于显示)。
在init.rb中进行初始化加载:
require 'enum_attr'
Object.send(:include, EnumAttr::Mixin)

然后就可以在model为中调用了, 如在user类中:
...
enum_attr(:gender, [['男', 0], ['女', 1]])
...

而编辑或创建页面都是一样的写法:
<%= f.label :gender,'Gender' %>:
<%= f.select :gender, User::ENUMS_GENDER %>


这个地方在编辑页面的时候也有效果,真是神奇。

显示的页面可以这样:

<%=h @user.gender_name %>


这个过程的解决方式非常的优雅,的确很强大。不过有些细节还是需要注意的,如,Object的send方法,作用是把EnumAttr::Mixin传给include方法,而include则是Object的一个内部方法,至于为什么要在前面加个冒号,细究起来还真是复杂,这里有两篇文章讲得很好:
http://www.cnitblog.com/gyn/archive/2007/09/18/15206.html
http://www.iteye.com/topic/109697
  • 大小: 13.7 KB
  • 大小: 7.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics