诗歌rails之 一个小技巧
虽然Rails提供了很多便利的内置方法,能够让我们快速处理开发中常见的需求,但还是会有要写大量相似代码的情景。
枚举类型的属性,比如用户的性别属性,在数据库里面用0/1表示男/女,我们有很多地方要用到这个属性:
再比如博客的类型属性,用0~3表示原创/翻译/转载/随笔等类型,也会有一堆相似的代码
利用ruby的module include和class eval等动态特性,我们可以方便地做一个plugin来mixin:
这样很容易地就增加了一个叫enum_attr的DSL:
然后我们就可以这样用:
通过将这些常用的功能插件化,能够更好地提高开发效率,你在开发中有将哪些功能组件化?欢迎交流。
枚举类型的属性,比如用户的性别属性,在数据库里面用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 %>
通过将这些常用的功能插件化,能够更好地提高开发效率,你在开发中有将哪些功能组件化?欢迎交流。
莫愁前路无知己,天下无人不识君。