今天细看了quakewang的那篇文章,获益匪浅,写得真是太好了.
[url]http://www.iteye.com/topic/448235[/url]
其实这篇文章已经写得非常的详细了,没有什么可写的。
但是为了缅怀一下,决定还是写一下,由于本人对ROR的学习时间并不长,只一个月左右,不管对ruby还是rails的理解都很有限,下面再介绍一下其过程。
在java中经常遇见数据库存储属性对应的值,而页面显示相应的名称。如['男', 0], ['女', 1]。数据库存储0或1,而页面显示男或女。处理的时候也有两种处理方式,一种是建立一个常量的类,通过Map来实现存取的常量。第二种是使用hibernate的特性,有个属性专门用来代替数据库某值存取,如把0替换成男,至于那个属性叫什么现在记不清了。
今天看了一下牛人在ror上实现方式,非常的不错,所以决定把详细过程再写一下。
一、首先解决数据库字段,建立一个迁移:
[img]http://dl.iteye.com/upload/attachment/279751/c5d7e449-a5c1-33a4-9e65-7f9d66b8843d.jpg[/img]
二、实现一个插件,虽然没有在书上看见过这方面的介绍,但其实很简单。
[img]http://dl.iteye.com/upload/attachment/279753/3f14ec88-361c-3eb9-81c8-052de85f1115.jpg[/img]
上面这张图是插件的目录结构。
首先看一下enum_attr.rb:
这段代码写得非常的精髓,要理解每一个细节还是得花点时间的,主要作用是在model类中建立ENUMS_#{attr.upcase}方法(用于遍历)、验证字段、#{attr}_name方法(用于显示)。
在init.rb中进行初始化加载:
然后就可以在model为中调用了, 如在user类中:
而编辑或创建页面都是一样的写法:
这个地方在编辑页面的时候也有效果,真是神奇。
显示的页面可以这样:
这个过程的解决方式非常的优雅,的确很强大。不过有些细节还是需要注意的,如,Object的send方法,作用是把EnumAttr::Mixin传给include方法,而include则是Object的一个内部方法,至于为什么要在前面加个冒号,细究起来还真是复杂,这里有两篇文章讲得很好:
[url]http://www.cnitblog.com/gyn/archive/2007/09/18/15206.html[/url]
[url]http://www.iteye.com/topic/109697[/url]
[url]http://www.iteye.com/topic/448235[/url]
其实这篇文章已经写得非常的详细了,没有什么可写的。
但是为了缅怀一下,决定还是写一下,由于本人对ROR的学习时间并不长,只一个月左右,不管对ruby还是rails的理解都很有限,下面再介绍一下其过程。
在java中经常遇见数据库存储属性对应的值,而页面显示相应的名称。如['男', 0], ['女', 1]。数据库存储0或1,而页面显示男或女。处理的时候也有两种处理方式,一种是建立一个常量的类,通过Map来实现存取的常量。第二种是使用hibernate的特性,有个属性专门用来代替数据库某值存取,如把0替换成男,至于那个属性叫什么现在记不清了。
今天看了一下牛人在ror上实现方式,非常的不错,所以决定把详细过程再写一下。
一、首先解决数据库字段,建立一个迁移:
[img]http://dl.iteye.com/upload/attachment/279751/c5d7e449-a5c1-33a4-9e65-7f9d66b8843d.jpg[/img]
二、实现一个插件,虽然没有在书上看见过这方面的介绍,但其实很简单。
[img]http://dl.iteye.com/upload/attachment/279753/3f14ec88-361c-3eb9-81c8-052de85f1115.jpg[/img]
上面这张图是插件的目录结构。
首先看一下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的一个内部方法,至于为什么要在前面加个冒号,细究起来还真是复杂,这里有两篇文章讲得很好:
[url]http://www.cnitblog.com/gyn/archive/2007/09/18/15206.html[/url]
[url]http://www.iteye.com/topic/109697[/url]