锁定老帖子 主题:将常用功能插件化 - 提高开发效率
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-14
利用ruby语言的动态特性,我们可以将这些代码组件化,举一个active record扩展的实际例子: 枚举类型的属性,比如用户的性别属性,在数据库里面用0/1表示男/女,我们有很多地方要用到这个属性: #在模型中我们需要写validate validates_inclusion_of :sex, :in => [0,1] #在页面上我们需要用tag生成下拉选择框 <%= form.select :sex, [['男', 0], ['女', 1]] %> #在显示输出的时候我们还要判断 <%= user.sex == 0 ? '男' : '女' %> 再比如博客的类型属性,用0~3表示原创/翻译/转载/随笔等类型,也会有一堆相似的代码 利用ruby的module include和class eval等动态特性,我们可以方便地做一个plugin来mixin: #plugins/your_plugin_name/lib/enum_attr.rb module EnumAttr module Mixin def enum_attr(attr, enums) 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}.find{|option| option[1] == #{attr}}[0] unless #{attr}.nil? end }) end end end #plugins/your_plugin_name/init.rb require 'enum_attr' Object.send :include, EnumAttr::Mixin 这样很容易地就增加了一个叫enum_attr的DSL: class User < ActiveRecord::Base enum_attr :sex, [['男', 0], ['女', 1]] end class Blog < ActiveRecord::Base enum_attr :blog_type, [['原创', 0], ['翻译', 1], ['转载', 2], ['随笔', 3]] end 然后我们就可以这样用: #在模型中我们不需要写validate了 ... #在页面上我们可以调用常量 <%= form.select :sex, User::ENUMS_SEX %> #在显示输出的时候我们可以直接调用扩展方法 <%= user.sex_name %> 通过将这些常用的功能插件化,能够更好地提高开发效率,你在开发中有将哪些功能组件化?欢迎交流。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-08-14
学习了。这种地方都是在Model中定义常量数组,值和显示都是一样的汉字。
|
|
返回顶楼 | |
发表时间:2009-08-14
最后修改:2009-08-14
非常不错,这样易维护,好理解。
我根据公司的实际需求情况,为了方便大家,将翻译功能搞到了一个插件中去了。 http://wiki.github.com/qichunren/acts_as_translatebox 然后使用起来很方便。 |
|
返回顶楼 | |
发表时间:2009-08-15
对于上面博客类型的例子,如果在state_machine插件里面加上这样的功能,会更加的好用.
|
|
返回顶楼 | |
发表时间:2009-08-15
qichunren 写道 非常不错,这样易维护,好理解。
我根据公司的实际需求情况,为了方便大家,将翻译功能搞到了一个插件中去了。 http://wiki.github.com/qichunren/acts_as_translatebox 然后使用起来很方便。 这个很赞! |
|
返回顶楼 | |
发表时间:2009-08-16
谢谢分享!
请问如果要有多语言的要求呢?写在model里面就不行了吧 |
|
返回顶楼 | |
发表时间:2009-08-18
最后修改:2009-08-18
好像一般性别都用 gender 而不是 sex, 要不然看起来总是浮想联翩
|
|
返回顶楼 | |
发表时间:2009-09-09
kilik52 写道 谢谢分享!
请问如果要有多语言的要求呢?写在model里面就不行了吧 enum_attr :sex, [[I18n.t("male"), 0], ['女', 1]] |
|
返回顶楼 | |
发表时间:2009-12-23
def #{attr}_name
ENUMS_#{attr.upcase}.find{|option| option[1] == #{attr}}[0]unless #{attr}.nil? end 很想知道ENUMS_#{attr.upcase}与find{|option| option[1] == #{attr}}中#{attr}有什么区别,按照代码的意思好像前一个#{attr}好像是指属性这里是"sex",后一个#{attr}是指值这里是0或1,晕了。 |
|
返回顶楼 | |
发表时间:2009-12-25
jayliud 写道 def #{attr}_name
ENUMS_#{attr.upcase}.find{|option| option[1] == #{attr}}[0]unless #{attr}.nil? end 很想知道ENUMS_#{attr.upcase}与find{|option| option[1] == #{attr}}中#{attr}有什么区别,按照代码的意思好像前一个#{attr}好像是指属性这里是"sex",后一个#{attr}是指值这里是0或1,晕了。 以sex为例,这段代码实际生成的就是: def sex_name # 这个模型本来就有sex方法(数据库字段),它存放的值就是0或1 ENUM_SEX.find { |option| option[1] == sex }[0] unless sex.nil? end 另外,sex这个词确实会令人浮想联翩 |
|
返回顶楼 | |