- 浏览: 2682950 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
80后的童年2:
深入浅出MongoDB应用实战开发网盘地址:https://p ...
MongoDB入门教程 -
shliujing:
楼主在不是精通java和php的前提下,请不要妄下结论。
PHP、CakePHP哪凉快哪呆着去 -
安静听歌:
希望可以一给一点点注释
MySQL存储过程之代码块、条件控制、迭代 -
qq287767957:
PHP是全宇宙最强的语言!
PHP、CakePHP哪凉快哪呆着去 -
rryymmoK:
深入浅出MongoDB应用实战开发百度网盘下载:链接:http ...
MongoDB入门教程
原文地址:A taxonomy of Rails plugins
Rails开发人员的一个最大的障碍是学习写插件的基础原则。Ruby的动态性和它所提供的代码重用的多种技术让写插件更复杂。
幸运的是,如果你可以写Rails程序,简单的按照一些基本的模式你也可以写插件。
本文的目的就是使用流行插件常用模式的例子来揭开写插件的神秘面纱。
为什么写插件?
写插件可以:
1,让代码分享更有效,无论是在不同的项目间抑或在同一项目里
2,允许你发布通用代码给社区
3,通过测试一次和重用多次来节省时间和增加你的信心
4,以一个健壮的方式分享功能性,特别是在ActiveRecord里使用名字空间时
使用
管理
Rails通过script/plugin install提供安装脚本,以及创建新插件的generator: script/generate plugin。它们将与URL一起工作,
当尝试插件时会节省时间。你可以在Rails wiki阅读关于安装和管理插件的更多信息。
创建
Rails提供一个generator来创建插件。执行如下命令:
这将在vendor/plugins/acts_as_目录生成一些文件,给你一些存根来让你填充。你将注意到生成一些用来安装、卸载和测试的文件
以及一些rake任务。许多插件不需要引入rake任务,并且安装和卸载插件时你可以做任何事情:也许你想让你的插件引入数据库表
(例如taggable插件需要数据库表来存储tags),或者你可能想在script/plugin install时检查依赖。
Rubyisms
下面Ruby提供的任一工具和技术都被插件用来扩展功能性:
1,Mixins:使用模块来引入或扩展类
2,打开一个类或模块定义并且添加或覆盖方法
3,通过回调和钩子来动态扩展:method_missing,Class#inherited,Module#const_missing,Module#included
4,通过代码生成来动态扩展:eval,class_eval,instance_eval
这些技术形成两种分类:
1,使用模块和类来扩展已有的类和提供新特性
2,使用自省来让一般代码适用于特殊情况
当写一个插件时考虑什么需要被扩展是很重要的。如果需要使用复杂的元编程来让你的插件适用于应用程序,则需要注意确保
同步不会产生不预期的结果。
扩展ActiveRecord
扩展ActiveRecord类的最流行的技术是通过使用模块和一个acts_as_类方法。大部分插件将它们自己分成包含类方法和实例方法
的两个模块,这让方法将在哪里使用很清晰。
添加新代码到ActiveRecord
为了使用你的新的acts_as_插件来扩展ActiveRecord::Base,最常见的技术是简单的添加如下内容到插件的init.rb文件:
你也可以使用class_eval来达到同样的效果。下面的例子来自acts_as_rateable:
注意使用公司名来为作者的插件创建一个名字空间。
下一步是使用持有acts_as_方法的模块来扩展ActiveRecord::Base。下面也是来自acts_as_rateable:
这样,任何ActiveRecord类都可以在类定义里使用acts_as_rateable。这样做将把提供的任何options发送到插件的ClassMethods
模块的acts_as_rateable方法里。
管理options
大部分插件在它们的acts_as_方法里使用extend和include来给接受的类提供类方法和实例方法。这也是options被处理的地方。
Options通常通过使用哈希来处理:
如果options被类方法和实例方法同时使用,则write_inheritable_attribute和class_inheritable_reader可以用来节省设置。
下面是一个修改过的acts_as_state_machine:
如此多的插件使用write_inheritable_attribute而不是cattr_方法有一个原因。考虑如果initial_state是一个类变量会发生什
么:其他使用该插件的对象将包含对同样的initial_state的引用。插件一般为不同的、可重用的代码,所以initial_state的一
个副本(而不是一个引用)是需要的。
重用一套关联和回调
acts_as_taggable_on_steroids阐述了插件的一个简单使用:
你可以看到,作者从插件的类方法里调用关联和回调。这是可以的,因为acts_as_taggable方法运行于接受类的定义里。
我发现我自己使用同样的技术来定义复杂而重用的关联(特别是重用多态has_many关联的情况)。
例如,我在一个基于组的使用回调和多态has_many关联的安全系统上工作。我写了一个插件来替代添加代码到每个需要基于组
的安全的类中。比较一下下面的代码:
原始代码:
该代码可以在我所有的项目间重用了,并且新的类可以“限制为”仅仅添加acts_as_restricted到类定义中。
这可以帮助节省时间--特别是当客户仍在犹豫什么应该被限制时。
结构
我宁愿通过为每个模块创建单独的文件来组织我的插件结构。这在acts_as_solr中阐述了,它为类方法使用一个单独的文件。
模块可以被类方法,实例方法和singleton方法使用。尽管可能看起来区分类方法和singleton方法很难,有些插件作者使用
这来阐明他们的代码。既然singleton方法适用于特殊的对象而不是一些对象,你可以根据需要高效的添加新方法到一个类的
特殊实例。
或者,对于acts_as_rateable,SingletonMethods模块用来区分添加到ActiveRecord的方法和那些添加到接受者的方法。
在这里finders被添加。
扩展ActionController和ActionView
ActiveRecord插件使用的同样的技术被用来扩展ActionController和ActionView。UploadProgress插件扩展了ActionView和
ActionController来添加它自己的helpers和controller功能性:
这样Controllers可以通过调用定义在UploadProgress::ClassMethods中的upload_status_for来使用插件。
最佳实践
1,为良好设计的插件避开对include的任意使用
2,仔细的结构化你的插件来确保它们很容易理解和测试
3,确保你使用write_inheritable_attribute和class_inheritable_reader这样你不会以引用设置而不是创建新的告终
4,将写测试作为设计过程中的一部分,不仅是因为插件可能写起来慢,而且当使用mongrel/webrick时它们不能重新加载
5,确保生成的SQL不会导致注射攻击:escape用户输入(我已经找到了生成原始SQL而不用escape变量的开源插件)
6,仔细考虑元编程代码的隐含意义,对eval和eval-like方法保持警惕。
下一步
本文将使用插件被如何测试的例子来继续。
引用
acts_as_rateable
acts_as_state_machine
acts_as_taggable_on_steroids
acts_as_solr
Rails Plugin Directory
Rails Wiki on plugins
Rails开发人员的一个最大的障碍是学习写插件的基础原则。Ruby的动态性和它所提供的代码重用的多种技术让写插件更复杂。
幸运的是,如果你可以写Rails程序,简单的按照一些基本的模式你也可以写插件。
本文的目的就是使用流行插件常用模式的例子来揭开写插件的神秘面纱。
为什么写插件?
写插件可以:
1,让代码分享更有效,无论是在不同的项目间抑或在同一项目里
2,允许你发布通用代码给社区
3,通过测试一次和重用多次来节省时间和增加你的信心
4,以一个健壮的方式分享功能性,特别是在ActiveRecord里使用名字空间时
使用
管理
Rails通过script/plugin install提供安装脚本,以及创建新插件的generator: script/generate plugin。它们将与URL一起工作,
当尝试插件时会节省时间。你可以在Rails wiki阅读关于安装和管理插件的更多信息。
创建
Rails提供一个generator来创建插件。执行如下命令:
script/generate plugin acts_as_
这将在vendor/plugins/acts_as_目录生成一些文件,给你一些存根来让你填充。你将注意到生成一些用来安装、卸载和测试的文件
以及一些rake任务。许多插件不需要引入rake任务,并且安装和卸载插件时你可以做任何事情:也许你想让你的插件引入数据库表
(例如taggable插件需要数据库表来存储tags),或者你可能想在script/plugin install时检查依赖。
Rubyisms
下面Ruby提供的任一工具和技术都被插件用来扩展功能性:
1,Mixins:使用模块来引入或扩展类
2,打开一个类或模块定义并且添加或覆盖方法
3,通过回调和钩子来动态扩展:method_missing,Class#inherited,Module#const_missing,Module#included
4,通过代码生成来动态扩展:eval,class_eval,instance_eval
这些技术形成两种分类:
1,使用模块和类来扩展已有的类和提供新特性
2,使用自省来让一般代码适用于特殊情况
当写一个插件时考虑什么需要被扩展是很重要的。如果需要使用复杂的元编程来让你的插件适用于应用程序,则需要注意确保
同步不会产生不预期的结果。
扩展ActiveRecord
扩展ActiveRecord类的最流行的技术是通过使用模块和一个acts_as_类方法。大部分插件将它们自己分成包含类方法和实例方法
的两个模块,这让方法将在哪里使用很清晰。
添加新代码到ActiveRecord
为了使用你的新的acts_as_插件来扩展ActiveRecord::Base,最常见的技术是简单的添加如下内容到插件的init.rb文件:
ActiveRecord::Base.send(:include, MyPlugin)
你也可以使用class_eval来达到同样的效果。下面的例子来自acts_as_rateable:
ActiveRecord::Base.class_eval do include FortiusOne::Acts::Rateable end
注意使用公司名来为作者的插件创建一个名字空间。
下一步是使用持有acts_as_方法的模块来扩展ActiveRecord::Base。下面也是来自acts_as_rateable:
module FortiusOne module Acts module Rateable def self.included(mod) mod.extend(ClassMethods) end module ClassMethods def acts_as_rateable(options = {}) end end
这样,任何ActiveRecord类都可以在类定义里使用acts_as_rateable。这样做将把提供的任何options发送到插件的ClassMethods
模块的acts_as_rateable方法里。
管理options
大部分插件在它们的acts_as_方法里使用extend和include来给接受的类提供类方法和实例方法。这也是options被处理的地方。
Options通常通过使用哈希来处理:
def acts_as_taggable(options = {})
如果options被类方法和实例方法同时使用,则write_inheritable_attribute和class_inheritable_reader可以用来节省设置。
下面是一个修改过的acts_as_state_machine:
def acts_as_state_machine(opts) self.extend(ClassMethods) raise NoInitialState unless opts[:initial] write_inheritable_attribute :initial_state, opts[:initial] class_inheritable_reader :initial_state
如此多的插件使用write_inheritable_attribute而不是cattr_方法有一个原因。考虑如果initial_state是一个类变量会发生什
么:其他使用该插件的对象将包含对同样的initial_state的引用。插件一般为不同的、可重用的代码,所以initial_state的一
个副本(而不是一个引用)是需要的。
重用一套关联和回调
acts_as_taggable_on_steroids阐述了插件的一个简单使用:
module ClassMethods def acts_as_taggable(options = {}) has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag has_many :tags, :through => :taggings before_save :save_cached_tag_list after_save :save_tags
你可以看到,作者从插件的类方法里调用关联和回调。这是可以的,因为acts_as_taggable方法运行于接受类的定义里。
我发现我自己使用同样的技术来定义复杂而重用的关联(特别是重用多态has_many关联的情况)。
例如,我在一个基于组的使用回调和多态has_many关联的安全系统上工作。我写了一个插件来替代添加代码到每个需要基于组
的安全的类中。比较一下下面的代码:
class Contact < ActiveRecord::Base acts_as_restricted end
原始代码:
class Contact < ActiveRecord::Base has_many :restrictions, :as => :restricted, :dependent => :destroy, :extend => ... before_save :auto_groups after_create :save_groups ...
该代码可以在我所有的项目间重用了,并且新的类可以“限制为”仅仅添加acts_as_restricted到类定义中。
这可以帮助节省时间--特别是当客户仍在犹豫什么应该被限制时。
结构
我宁愿通过为每个模块创建单独的文件来组织我的插件结构。这在acts_as_solr中阐述了,它为类方法使用一个单独的文件。
模块可以被类方法,实例方法和singleton方法使用。尽管可能看起来区分类方法和singleton方法很难,有些插件作者使用
这来阐明他们的代码。既然singleton方法适用于特殊的对象而不是一些对象,你可以根据需要高效的添加新方法到一个类的
特殊实例。
或者,对于acts_as_rateable,SingletonMethods模块用来区分添加到ActiveRecord的方法和那些添加到接受者的方法。
在这里finders被添加。
扩展ActionController和ActionView
ActiveRecord插件使用的同样的技术被用来扩展ActionController和ActionView。UploadProgress插件扩展了ActionView和
ActionController来添加它自己的helpers和controller功能性:
ActionController::Base.send(:include, UploadProgress) ActionView::Base.send(:include, UploadProgress::UPloadProgressHelper)
这样Controllers可以通过调用定义在UploadProgress::ClassMethods中的upload_status_for来使用插件。
最佳实践
1,为良好设计的插件避开对include的任意使用
2,仔细的结构化你的插件来确保它们很容易理解和测试
3,确保你使用write_inheritable_attribute和class_inheritable_reader这样你不会以引用设置而不是创建新的告终
4,将写测试作为设计过程中的一部分,不仅是因为插件可能写起来慢,而且当使用mongrel/webrick时它们不能重新加载
5,确保生成的SQL不会导致注射攻击:escape用户输入(我已经找到了生成原始SQL而不用escape变量的开源插件)
6,仔细考虑元编程代码的隐含意义,对eval和eval-like方法保持警惕。
下一步
本文将使用插件被如何测试的例子来继续。
引用
acts_as_rateable
acts_as_state_machine
acts_as_taggable_on_steroids
acts_as_solr
Rails Plugin Directory
Rails Wiki on plugins
发表评论
-
用了TextMate才知道什么叫神级Editor
2011-03-09 04:51 57996一直用Eclipse作为开发Ruby和Java项目的IDE,但 ... -
Ruby使用OAuth登录新浪微博和豆瓣
2011-01-09 12:49 4464首先需要安装oauth这个gem包 gem install ... -
使用Passenger+nginx部署Rails
2010-12-28 15:12 50331. Install Passender gem instal ... -
markItUp+rdiscount搭建Rails下可视化Markdown编辑器
2010-12-21 17:48 5470markItUp是基于jQuery的可视化编辑器,支持Html ... -
Rails3 and MongoDB Quick Guide
2010-12-10 14:13 2760Install MongoDB Download: http: ... -
基于ruby-protobuf的rpc示例
2009-08-11 11:51 41521, 安装ruby-protobuf gem instal ... -
Ruby导出xls和csv的utf-8问题的解决
2009-02-04 15:05 6857数据库数据为utf-8格式,包括中文和拉丁文等等 导出文件xl ... -
URL/HTML/JavaScript的encode/escape
2009-01-04 13:03 9346最近经常被URL、HTML、JavaScript的encode ... -
各种排序的Ruby实现
2008-11-27 14:51 4007Θ(n^2) 1, Bubble sort def bu ... -
12月5日北京RoR活动!
2008-11-26 18:38 3024又是一年过去了,Rails在国内的发展势态良好,很多使用RoR ... -
Rails程序开发的最大问题是代码规范
2008-08-28 11:56 5580使用Rails开发大型复杂B2B应用一年了,这个项目目前开发人 ... -
Web开发大全:ROR版——推荐序
2008-07-09 00:39 2430来自http://www.beyondrails.com/bl ... -
深入ActionMailer,使用Sendmail发邮件
2008-07-03 11:41 3399来自: http://www.beyondrails.com/ ... -
Rails里如何结合ExceptionNotification配置gmail账户发邮件
2008-06-19 19:56 31031,安装ExceptionNotification rub ... -
使用coderay和railscasts样式进行代码高亮
2008-06-17 00:16 2400CodeRay是一个语法高亮的Ruby库,效率很不错。 Cod ... -
Capistrano试用
2008-06-16 19:05 19631,客户端机器安装Capistrano gem insta ... -
lighttpd真垃圾啊
2008-06-04 18:38 2548使用lighttpd+fcgi跑Rails程序,文件上传会si ... -
将gem变成plugin
2008-06-04 11:27 1809有什么样的需求就有什么样的对策 当vhost上的帐号没有ge ... -
在Rails里使用ReCaptcha添加验证码
2008-06-03 15:51 42741,去http://recaptcha.net/sign up ... -
Rails里给文件上传添加progress_bar
2008-05-27 17:00 2098文件上传很慢时,UI没有什么用户提示,这样让人很费解,所以我们 ...
相关推荐
1. Rails插件的作用和分类:介绍不同类型的Rails插件,如Devise用于身份验证,CanCanCan处理权限控制,Bootstrap-Sass为视图添加响应式设计等。 2. 如何查找和选择Rails插件:介绍GitHub、RubyGems等平台,讲解如何...
Exception Notification是一款非常实用的Rails插件,它能够自动捕获并报告应用在运行过程中出现的各种异常情况,帮助开发者及时获取错误信息,提高问题解决效率。 Exception Notification插件的核心功能是在Rack或...
第十七章讲解了 **Rails 引擎**,这是一种可以被其他 Rails 应用作为插件使用的独立 Rails 应用。 - **Rails 引擎**: - 类似于插件,但更加强大和灵活。 - 可以提供额外的功能,如电子商务模块、论坛系统等。 #...
在这个特定的场景中,我们关注的是一个名为 "Breadcrumbs on Rails" 的插件,它提供了一种简单的方式来创建和管理面包屑导航在你的 Rails 应用程序中。 面包屑导航是一种用户界面元素,它帮助用户理解他们在网站或...
Rails社区活跃,拥有丰富的插件和gem(Ruby的包管理器),如Devise用于身份验证,CanCanCan进行权限控制,Paperclip或Carrierwave用于文件上传等。这些gem极大扩展了Rails的功能,加速了开发进程。 在本教程中,你...
Ruby-ActsAsTaggableOn 是一个非常流行的Rails插件,用于在动态环境中实现自定义标签功能。这个插件使得在你的Rails应用中添加标签系统变得简单高效,它提供了灵活的接口来管理和操作标签数据。 首先,让我们深入...
- **模块化改进:** 支持插件系统,允许开发者轻松扩展和定制Rails的功能。 - **社区贡献:** Rails 2更加注重社区的反馈和贡献,这使得框架能够更快地响应用户需求并修复问题。 #### 五、实战案例分析 本书通过...
12. **Kaminari** 和 **WillPaginate**:分页插件,帮助处理大量数据的显示。 13. **Ransack**:提供强大的搜索和过滤功能,让用户可以根据需要自定义搜索条件。 14. **SimpleForm** 和 **Formtastic**:简化Rails...
RailsAdminJstree是一款专为Rails管理界面RailsAdmin设计的扩展插件,它引入了树形视图功能,使得在后台管理系统中可以更方便地处理层级关系的数据。RailsAdmin是一款强大的Ruby on Rails gem,用于快速构建后台管理...
5. **可扩展性**:Forem的设计允许开发者通过编写插件或者扩展来增加新的功能,例如集成社交媒体分享、添加积分系统等。 6. **自定义主题和样式**:Forem支持CSS和模板的自定义,可以根据需求调整论坛的外观和布局...
为了构建无插件的Web应用,后端技术也非常重要,可能使用的有Node.js、Django、Ruby on Rails或者Spring Boot等,它们能够处理HTTP请求、数据库交互和服务器端逻辑。 文件包可能还包括一个或多个构建工具,如...
3. **分类与标签**:对文章进行分类和打标签,方便用户浏览和搜索。 4. **评论系统**:集成评论功能,可能支持社交媒体登录和垃圾评论过滤。 5. **SEO优化**:提供元标签编辑,优化搜索引擎索引。 6. **社交分享**:...
- **灵活扩展**:Rails框架提供了丰富的插件和gem(Ruby的库),使得Rabel可以轻松添加新的功能或集成其他服务。 **4. 安装与部署** 要运行Rabel,首先需要安装Ruby环境,然后通过RubyGems安装Rails。接着克隆Rabel...
4. **Ruby on Rails**:尽管主要讨论的是 JavaScript 插件,但了解 Rails 框架的基本概念对于整体理解 Discourse 的运作是必要的。 5. **Git 版本控制**:"master" 分支的提及意味着要熟悉 Git 的工作流程,包括克隆...
4. **可扩展性**:作为 gem,rglossa 可以方便地与其他 Rails 应用集成,或者通过插件机制扩展其功能。 **JavaScript 在 rglossa 中的角色** 虽然主要基于 Ruby on Rails,但 `rglossa` 还利用了 JavaScript 来增强...
我们使用相同的 Ruby on Rails Active 支持字符串辅助方法来简化字符串操作。 #A Jquery Plugins For Some String Helper methods like Camelize, Underscore, Dasherize, Classify, Ordinalize, ForeignKey 所有...
为了创建RoR News-crx插件,开发者可能使用了Ruby on Rails(RoR)框架,这是一个流行的开源Web开发框架,以其MVC(模型-视图-控制器)架构和“约定优于配置”的理念而闻名。Rails支持快速开发,使得创建这样的扩展...
为了安装和使用cosmoSys RM插件,用户通常需要熟悉Ruby on Rails框架,以及Redmine的插件管理和部署流程。这可能涉及到解压文件、将插件代码放入Redmine的指定目录、运行数据库迁移、重启Redmine服务等一系列步骤。 ...