诗歌rails之 一个小技巧

虽然Rails提供了很多便利的内置方法,能够让我们快速处理开发中常见的需求,但还是会有要写大量相似代码的情景。
利用ruby语言的动态特性,我们可以将这些代码组件化,举一个active record扩展的实际例子:
枚举类型的属性,比如用户的性别属性,在数据库里面用0/1表示男/女,我们有很多地方要用到这个属性:
Ruby代码
  1. #在模型中我们需要写validate
  2. validates_inclusion_of :sex, :in => [0,1]
  3. #在页面上我们需要用tag生成下拉选择框
  4. <%= form.select :sex, [['男', 0], ['女', 1]] %>
  5. #在显示输出的时候我们还要判断
  6. <%= user.sex == 0 ? '男' : '女' %>

再比如博客的类型属性,用0~3表示原创/翻译/转载/随笔等类型,也会有一堆相似的代码

利用ruby的module include和class eval等动态特性,我们可以方便地做一个plugin来mixin:
Ruby代码
  1. #plugins/your_plugin_name/lib/enum_attr.rb
  2. module EnumAttr
  3. module Mixin
  4. def enum_attr(attr, enums)
  5. attr = attr.to_s
  6. self.class_eval(%Q{
  7. ENUMS_#{attr.upcase} = enums
  8. validates_inclusion_of attr, :in => enums.map{|e| e[1]}, :allow_nil => true
  9. def #{attr}_name
  10. ENUMS_#{attr.upcase}.find{|option| option[1] == #{attr}}[0] unless #{attr}.nil?
  11. end
  12. })
  13. end
  14. end
  15. end
  16. #plugins/your_plugin_name/init.rb
  17. require 'enum_attr'
  18. Object.send :include, EnumAttr::Mixin


这样很容易地就增加了一个叫enum_attr的DSL:
Ruby代码
  1. class User < ActiveRecord::Base
  2. enum_attr :sex, [['男', 0], ['女', 1]]
  3. end
  4. class Blog < ActiveRecord::Base
  5. enum_attr :blog_type, [['原创', 0], ['翻译', 1], ['转载', 2], ['随笔', 3]]
  6. end

然后我们就可以这样用:
Ruby代码
  1. #在模型中我们不需要写validate了
  2. ...
  3. #在页面上我们可以调用常量
  4. <%= form.select :sex, User::ENUMS_SEX %>
  5. #在显示输出的时候我们可以直接调用扩展方法
  6. <%= user.sex_name %>


通过将这些常用的功能插件化,能够更好地提高开发效率,你在开发中有将哪些功能组件化?欢迎交流。
posted @ 2009-08-17 20:44  麦飞  阅读(435)  评论(0编辑  收藏  举报