`
suchj
  • 浏览: 146323 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何写rails插件

    博客分类:
  • ruby
阅读更多

如何实现一个简单的插件?下面实现一个在model中能输出hello world的插件。

注:()中的斜体是本人的心得体会,可忽略。

 

第一步,在工程目录下新建一个插件,运行

rails generate plugin HelloWorld


这个命令会生成以下目录文件:

      create  vendor/plugins/hello_world
      create  vendor/plugins/hello_world/MIT-LICENSE
      create  vendor/plugins/hello_world/README
      create  vendor/plugins/hello_world/Rakefile
      create  vendor/plugins/hello_world/init.rb
      create  vendor/plugins/hello_world/install.rb
      create  vendor/plugins/hello_world/uninstall.rb
      create  vendor/plugins/hello_world/lib
      create  vendor/plugins/hello_world/lib/hello_world.rb
      invoke  test_unit
      inside    vendor/plugins/hello_world
      create      test
      create      test/hello_world_test.rb
      create      test/test_helper.rb

这里面比较重要的文件就是init.rb和lib/hello_world.rb,在插件被加载时,init.rb会先被加载,完成初始化,lib下放实现代码库。

 

第二步,编辑lib下的hello_world.rb文件,定义一个实现输出Hello World的方法say

hello_world.rb:

module HelloWorld
   def say
     p 'Hello World!'
   end
end

 

第三步,插件完成了,下面在model中使用这个插件。在init.rb文件里加入

init.rb:

ActiveRecord::Base.send(:include, HelloWorld)

这样就为所有的model都混入了HelloWorld,say方法也就成了model里的实例方法了。


这样就在ActiveRcord:Base里混入了HelloWorld模块,而model又是继承于ActiveRecord::Base,所以model就能直接调用HelloWorld中的静态方法了。
send所发送的消息,在程序运行时是可变的,而且,send还能打开module或类中的private方法,使用上更加灵活。


在model中使用,post.rb:

class Post < ActiveRecord::Base
end
 

在控制台中看一下结果: 

1.8.7 :001 >  Post.new.say
"Hello World!"
 => nil 

没有问题!一个简单的插件就完成了,但这样HelloWorld里的方法对所有的model都是打开的,如果不想这样,可以这样这样写

hello_world.rb:

module HelloWorld
   def self.included(base)
     base.extend(ClassMethods)
   end
   
   module ClassMethods    
      def hellolize 
        include HelloWorld::InstanceMethods
      end                  
   end
 
   module InstanceMethods
     def say
       p 'Hello World!'
     end
   end
end

 

当HelloWorld模块被include时,方法included将被调用,混含的类的名字被传入,再调用了extend方法,ClassMethods模块中的方法就成了混入类中的类方法了,就可以直接调用了。当hellolize方法被调用时,InstanceMethods就被混入类中了,成了混入类中的实例方法了。这样做的好处是,我想在哪个model里便用say方法,就在哪个model里调用hellolize方法,这样做保证了方法的安全性


init.rb:

ActiveRecord::Base.send(:include, HelloWorld)


在model中使用,post.rb:

class Post < ActiveRecord::Base
  hellolize
end

 

在控制台中看一下结果: 

1.8.7 :001 > Post.new.say
"Hello World!"
 => nil 

 

以上只是一个实现过程,可以根据实际情况把重复功能代码写成插件使用。

当然,一个完整的插件有完整的验证和测试,此例子纯粹供练手,仅供参考。

 

这里有个比较好的例子:http://railscasts.com/episodes/33-making-a-plugin?view=asciicast

0
0
分享到:
评论
1 楼 coldrush 2013-04-25  
学习了,挺好

相关推荐

Global site tag (gtag.js) - Google Analytics