虽然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 %>


    通过将这些常用的功能插件化,能够更好地提高开发效率,你在开发中有将哪些功能组件化?欢迎交流。

    相关文章:

    • 2022-01-08
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    猜你喜欢
    • 2021-08-12
    • 2022-12-23
    • 2021-05-30
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    相关资源
    相似解决方案