1.
在上一篇文章中,我们介绍了如何使用edit field来编辑日期和时间,而不是用很多的dropdown menus. 那些日期和时间首先被用文本输入到一个编辑框中,然后被rails用自带的日期解析函数解析成日期和时间存储到数据库中。
例如:
Task name: Task 1
Due at time string:
2009-08-20 08:00:00
为了完成这个任务,我们为Task model创建了一个虚拟属性,叫做due_at_string, 这个属性具有 get method 和 set method, get method 从数据库中读取due_at 字段,然后以某种格式的字符串显示出来, set method则解析用户输入的字符串,将其转化成日期时间类型,并存储到数据库的due_at 字段中, 具体代码如下:
这种为某一个属性单独写set method 和 get method的做法处理某一个属性当然可以,但是如果需要单独写set和get 的属性很多呢,例如还有许多其他字段也是日期时间格式?我们代码会有很多的重复。
为了解决这个问题,我们的方法是添加一个类方法,名字叫stringify_time。
这个方法的作用就是动态的为每一个传给他的属性自动创建getter和setter方法。cool把
而且可以预计到,这个方法我们在其他的项目中也会经常用到,因此我们要把他封装成一个plugin。呵呵
2. Create Plugin:
首先,我们要generate 一个空的plugin 名字叫 stringify_time
命令如下:
这个命令将在我们的工程的vender/plugins文件夹生成一个新的叫stringify_time的文件夹
我们先来看看init.rb文件, 这个是初始化文件,它将在plugin 被load in 之前load 进来,因此,这里我们要在init.rb 中添加如下一行:
这行代码将会把lib目录下的stringify_time.rb 文件load 进来。
而在lib/stringify_time.rb 文件中,这里是主要代码所在地,我们将在这里添加类似的getter 和 setter methods, 我们首先要定义一个module,其中含有stringify_time 方法。
stringify_time这个方法将接收多个字段名字作为参数,这里我们用*names,表示这个方法可以接收多个参数,所有参数构成一个叫names的数组供方法内部调用,这个是个很有用的小知识,一般人我不告诉他哦!
在方法内部,循环使用数组中的名字,使用define_method这个方法,动态的创建名字叫[name]_string 的方法,那么如果我们传递due_at给这个方法,我们就会得到due_at_string方法。
define_method 这个方法接收一个block,block内的代码就是动态定义的方法的内容,以之前的due_at_string方法为例,这个方法从数据库中读取due_at字段,然后将其日期时间类型转换成一个字符串返回,但是这里不能用dua_at 这个名字了,只能用read_attribute 方法获得字段:
就是这么简单,我们就创建了很多属性的getter方法。
同样的,我们照葫芦画瓢写出动态创建setter方法的类方法
哇噻,太牛逼的程序了,可惜不是我写的,嘿嘿!!!!
可以看到,在setter method 中,我们仍然使用了define_method方法,但是要setter method要接收参数,这个参数可以放在随后的block中.
全部代码如下:
稍等,我们已经写好了plugin,但是在程序中如何让没有active record model自动具有这个pulgin的功能呢,这就需要将这个plugin中的的module extend到ActiveRecord::Base这个类中,这个工作要放在init.rb中:
注意我们用的是extend而不是include, extend的作用是将module中的方法作为类方法而不是实例方法添加到ActiveRecord::Base中,因为我们的stringify_time是类方法,而不是实例方法,因为这个方法的运行不需要有任何对象。
而include 将会把StringifyTime中的方法作为实例方法放入到ActiveRecord::Base中。
3. 既然我们已经制作了plugin,而且把他包含进了ActiveRecord::Base类中,那么接下来就是如何使用他了,在我们的Task模型中:
4. 完善:
我们发现在validate方法中,我们用@due_at_invalid这个实例变量来判断,但是这个实例变量是在plugin中定义的,这里突然冒出来,后面的开发者很可能不知道他是哪里来的,因此我们最好使用方法而不是直接使用实例变量:
而这个方法的定义自然也应该放在plugin中:
define_method "#{name}_invalid?" do
return instance_variable_get("#{name}_invalid")
end
至此,我们终于完成了一个plugin的制作。
如果你要在其他的项目中复用这个plugin,只要把这个目录拷贝到该项目的vender/plugin目录下即可,很简单把,嘿嘿。
5. 再说一点题外话:
关于block,例如
这就是一个 后面可以跟着block的方法的定义和使用的全过程。
在上一篇文章中,我们介绍了如何使用edit field来编辑日期和时间,而不是用很多的dropdown menus. 那些日期和时间首先被用文本输入到一个编辑框中,然后被rails用自带的日期解析函数解析成日期和时间存储到数据库中。
例如:
Task name: Task 1
Due at time string:
2009-08-20 08:00:00
为了完成这个任务,我们为Task model创建了一个虚拟属性,叫做due_at_string, 这个属性具有 get method 和 set method, get method 从数据库中读取due_at 字段,然后以某种格式的字符串显示出来, set method则解析用户输入的字符串,将其转化成日期时间类型,并存储到数据库的due_at 字段中, 具体代码如下:
def due_at_string due_at.to_s(:db) end def due_at_string=(due_at_str) self.due_at = Time.parse(due_at_str) rescue ArguementError @due_at_invalid = true end
这种为某一个属性单独写set method 和 get method的做法处理某一个属性当然可以,但是如果需要单独写set和get 的属性很多呢,例如还有许多其他字段也是日期时间格式?我们代码会有很多的重复。
为了解决这个问题,我们的方法是添加一个类方法,名字叫stringify_time。
这个方法的作用就是动态的为每一个传给他的属性自动创建getter和setter方法。cool把
而且可以预计到,这个方法我们在其他的项目中也会经常用到,因此我们要把他封装成一个plugin。呵呵
2. Create Plugin:
首先,我们要generate 一个空的plugin 名字叫 stringify_time
命令如下:
script/generate plugin stringify_time
这个命令将在我们的工程的vender/plugins文件夹生成一个新的叫stringify_time的文件夹
我们先来看看init.rb文件, 这个是初始化文件,它将在plugin 被load in 之前load 进来,因此,这里我们要在init.rb 中添加如下一行:
这行代码将会把lib目录下的stringify_time.rb 文件load 进来。
require 'stringify_time'
而在lib/stringify_time.rb 文件中,这里是主要代码所在地,我们将在这里添加类似的getter 和 setter methods, 我们首先要定义一个module,其中含有stringify_time 方法。
module StringifyTime def stringify_time(*names) end end
stringify_time这个方法将接收多个字段名字作为参数,这里我们用*names,表示这个方法可以接收多个参数,所有参数构成一个叫names的数组供方法内部调用,这个是个很有用的小知识,一般人我不告诉他哦!
在方法内部,循环使用数组中的名字,使用define_method这个方法,动态的创建名字叫[name]_string 的方法,那么如果我们传递due_at给这个方法,我们就会得到due_at_string方法。
define_method 这个方法接收一个block,block内的代码就是动态定义的方法的内容,以之前的due_at_string方法为例,这个方法从数据库中读取due_at字段,然后将其日期时间类型转换成一个字符串返回,但是这里不能用dua_at 这个名字了,只能用read_attribute 方法获得字段:
def stringify_time(*names) names.each do |name| define_method "#{name}_string" do read_attribut(name).to_s(:db) end end end
就是这么简单,我们就创建了很多属性的getter方法。
同样的,我们照葫芦画瓢写出动态创建setter方法的类方法
names.each do |name| define_method "#{name}_string=" do |time_str| begin write_attribute(name, Time.parse(time_str)) rescue ArgumentError instance_variable_set("@#{name}_invalid", true) end end end
哇噻,太牛逼的程序了,可惜不是我写的,嘿嘿!!!!
可以看到,在setter method 中,我们仍然使用了define_method方法,但是要setter method要接收参数,这个参数可以放在随后的block中.
全部代码如下:
module StringifyTime def stringify_time(*names) names.each do |name| define_method "#{name}_string" do read_attribute(name).to_s(:db) end define_method "#{name}_string=" do |time_str| begin write_attribute(name, Time.parse(time_str)) rescue ArgumentError instance_variable_set("@#{name}_invalid", true) end end end end end
稍等,我们已经写好了plugin,但是在程序中如何让没有active record model自动具有这个pulgin的功能呢,这就需要将这个plugin中的的module extend到ActiveRecord::Base这个类中,这个工作要放在init.rb中:
class ActiveRecore:Base extend StringifyTime end
注意我们用的是extend而不是include, extend的作用是将module中的方法作为类方法而不是实例方法添加到ActiveRecord::Base中,因为我们的stringify_time是类方法,而不是实例方法,因为这个方法的运行不需要有任何对象。
而include 将会把StringifyTime中的方法作为实例方法放入到ActiveRecord::Base中。
3. 既然我们已经制作了plugin,而且把他包含进了ActiveRecord::Base类中,那么接下来就是如何使用他了,在我们的Task模型中:
class Task < ActiveRecord::Base belongs_to :project stringify_time :due_at def validate errors.add(:due_at, "is_invalid") if @due_at_invalid end end
4. 完善:
我们发现在validate方法中,我们用@due_at_invalid这个实例变量来判断,但是这个实例变量是在plugin中定义的,这里突然冒出来,后面的开发者很可能不知道他是哪里来的,因此我们最好使用方法而不是直接使用实例变量:
def validate errors.add(:due_at, "is_invalid") if due_at_invalid? end
而这个方法的定义自然也应该放在plugin中:
define_method "#{name}_invalid?" do
return instance_variable_get("#{name}_invalid")
end
至此,我们终于完成了一个plugin的制作。
如果你要在其他的项目中复用这个plugin,只要把这个目录拷贝到该项目的vender/plugin目录下即可,很简单把,嘿嘿。
5. 再说一点题外话:
关于block,例如
class File def File.open_and_process(*args) f = File.open(*args) yield f f.close end end File.open_and_process('testfile', 'r') do |file| while line=file.gets puts line end end
这就是一个 后面可以跟着block的方法的定义和使用的全过程。
发表评论
-
12.3.3 scaling issue of the status feed
2011-10-30 17:54 825the problem of the implementati ... -
12.3 the status feed
2011-10-30 15:34 8611. we need to get all the micro ... -
12.2 a working follow button with Ajax
2011-10-29 18:10 9141. in the last chapter, in the ... -
12.2 a web interface for following and followers.
2011-10-28 22:14 8801.before we do the UI, we need ... -
12. following user, 12.1 relationship model
2011-10-18 14:29 7551. we need to use a relationshi ... -
11.3 manipulating microposts.
2011-10-17 15:31 9011. since all micropost actions ... -
11.2 show microposts.
2011-10-17 12:01 7051. add test to test the new use ... -
11.1 user micropost -- a micropost model.
2011-10-17 10:43 11081. we will first generate a mic ... -
10.4 destroying users.
2011-10-16 15:47 747in this chapter, we will add de ... -
10.3 showing users list
2011-10-15 20:41 778in this chapter, we will do use ... -
10.2 protect pages.
2011-10-15 15:11 668again, we will start from TD ... -
10.1 updating users.
2011-10-14 18:30 7101. git checkout -b updating-use ... -
9.4 sign out
2011-10-13 15:21 738whew!!!, last chapter is a long ... -
9.3 sign in success.
2011-10-12 15:39 7511. we will first finish the cre ... -
9.1 about flash.now[:error] vs flash[:error]
2011-10-12 15:37 727There’s a subtle difference ... -
9.2 sign in failure
2011-10-12 12:19 660start from TDD!!! 1. requir ... -
9.1 sessions
2011-10-12 10:00 645a session is a semi-permanent c ... -
what test framework should you use?
2011-10-11 16:56 0for integration test, i have no ... -
what test framework should you use?
2011-10-11 16:56 0<p>for integration test, ... -
8.4 rspec integration tests
2011-10-11 16:53 723in integration test, you can te ...
相关推荐
64bit Plugin & key 64bit Plugin & key
- **SpacEyes3D Software Development Kit (SDK)**:作为核心开发工具包,SpacEyes3D SDK使第三方程序能够在SpacEyes3D Plugin的基础上进行扩展和定制。它包含了创建、编辑和操作三维虚拟项目的必要组件和API。 - *...
PidginHost Selenium Plugin & SSH Testing Suite
JAVA视频教程(三) - Plugin & RCP开发 http://blog.csdn.net/gonxi/archive/2006/02/12/597312.aspx
QT-Plugin的创建和使用是Qt框架中一个重要的特性,它允许程序在运行时动态加载新的功能或组件,极大地增强了软件的灵活性和可扩展性。本文将深入探讨如何创建和使用QT-Plugin,并通过实际例子来阐述相关知识点。 ...
总的来说,"Ita-IDE-Plugin"是一款为Delphi IDE增添趣味性和实用性的插件,它通过提供自定义背景图片的功能,帮助开发者打造个性化的工作空间,让编程过程更加愉快。对于那些注重开发环境体验的程序员来说,这无疑是...
"VEEAM Rman Plugin for Oracle安装和使用手册" VEEAM Rman Plugin for Oracle是VEEAM公司开发的一款插件,旨在为Oracle RAC数据库提供备份和恢复解决方案。该插件可以与VEEAM Backup & Replication集成,提供了一...
同时,需要遵循DroidPlugin定义的特定规范,如使用特殊的Activity声明和Intent过滤器。 3. **宿主集成**:宿主应用需要集成DroidPlugin框架,这通常涉及到对AndroidManifest.xml的修改,以及对项目构建脚本的调整,...
2. **插件加载**:找到插件后,PluginManager会使用C#的反射机制来加载和实例化这些插件。反射允许程序在运行时检查类型信息,并动态创建对象实例。 3. **依赖注入**:为了使插件能够正常工作,PluginManager可能...
"alink-plugin"是一个基于Alink框架的插件系统,它扩展了Alink的核心功能,使得开发者可以更加便捷地实现特定的数据处理和机器学习任务。Alink是阿里巴巴开源的一个实时流计算框架,它提供了丰富的算法库,支持大...
正确理解和使用Maven Plugin,可以帮助开发者提高构建效率,确保项目的质量和一致性。对于`maven plugin打包下载`这个主题,理解其工作原理、生命周期和配置方式至关重要,这将直接影响到项目的构建和打包过程。
在 Maven 中,插件是通过 Maven 插件管理系统(scm)进行管理和使用的。这个主题主要围绕 Maven 插件的使用、其与 SCM(版本控制系统)的集成以及如何利用 Maven 插件与 Ant 集成来进行项目管理与构建。 首先,让...
Maven 使用 tomcat8-maven-plugin 插件 Maven 是一个流行的构建自动化工具,它可以帮助开发者自动完成项目的编译、测试、打包、部署等任务。...在本文中,我们详细介绍了 tomcat8-maven-plugin 插件的使用方法和优点。
总之,“wxa-plugin-canvas-master”是一个强大的微信小程序海报生成解决方案,它利用canvas的强大绘图能力,帮助开发者轻松创建个性化的海报,提升了小程序的用户体验和互动性。正确理解和运用这个组件,能够为你的...
当maven-site-plugin和maven-scr-plugin同时使用时,可能遇到的问题是,site plugin试图清理target目录以准备生成新的站点文档,但因为maven-scr-plugin生成的服务元数据(通常位于target/OSGI-INF/serviceComposite...
本文将重点探讨NotePad++的一款重要插件——AnalysePlugin,帮助用户更高效地分析和处理复杂日志。 AnalysePlugin是一款专门针对NotePad++设计的插件,旨在提高开发者对大型复杂日志文件的分析能力。在处理大量系统...
code & plugin.part1 code & plugin.part1 code & plugin.part1 code & plugin.part1 code & plugin.part1
code & plugin.part2 code & plugin.part2 code & plugin.part2 code & plugin.part2 code & plugin.part2
例如,你可以定义一个`IPlugin`接口,包含`start()`和`stop()`方法,供插件在加载和卸载时使用。 接下来,你需要创建一个实现该接口的插件类。这个类继承自接口,并实现其定义的所有功能。在我们的示例程序...
WordPress原创插件:Download-block-plugin下载按钮图标美化