- ruby scriptgenerate plugin MyPlugin
ruby scriptgenerate plugin MyPlugin
功能需求: 在BlogController中把所有符合条件的Post(Model)生成为xml
如果不使用插件,很easy :
in BlogController
- def export_to_xml
- posts = Post.find(:all, :order => 'published_date',
- :conditions => ['title = ?', 'love'])
- send_data posts.to_xml, :type => 'text/xml; charset=UTF-8;',
- :disposition => "attachment; filename=posts.xml"
- end
def export_to_xmlposts = Post.find(:all, :order => 'published_date',:conditions => ['title = ?', 'love'])send_data posts.to_xml, :type => 'text/xml; charset=UTF-8;',:disposition => "attachment; filename=posts.xml"
end
如果使用插件,我们要求能这样:
- class BlogController < ApplicationController
- my_plugin :post
- def to_xml
- export_to_xml
- end
- end
class BlogController < ApplicationControllermy_plugin :postdef to_xmlexport_to_xmlend
end
OK,立刻满足以上的要求,进入你的project:
生成plugin
- ruby scriptgenerate plugin MyPlugin
ruby scriptgenerate plugin MyPlugin
and than to find: vendor/plugins/my_plugin/lib/my_plugin.rb
接着就是edit了:
- module MyPlugin
- def self.included(base)
- base.extend(ClassMethods)
- end
- class Config
- attr_reader :model
- attr_reader :model_id
- def initialize(model_id)
- @model_id = model_id
- @model = model_id.to_s.camelize.constantize
- end
- def model_name
- @model_id.to_s
- end
- end
- module ClassMethods
- def my_plugin(model_id = nil)
- model_id = self.to_s.split('::').last.sub(/Controller$/, '').pluralize.singularize.underscore unless model_id
- @my_plugin_config = MyPlugin::Config.new(model_id)
- include MyPlugin::InstanceMethods
- end
- def my_plugin_config
- @my_plugin_config || self.superclass.instance_variable_get('@my_plugin_config')
- end
- end
- module InstanceMethods
- def export_to_xml
- data = self.class.my_plugin_config.model.find(:all, :order => 'published_date', :conditions => conditions_for_collection)
- send_data data.to_xml, :type => 'text/xml; charset=UTF-8;',
- :disposition => "attachment; filename=#{self.class.my_plugin_config.model_name.pluralize}.xml"
- end
- # 在controller中覆盖此method,写入满足的条件
- def conditions_for_collection
- end
- end
- end
module MyPlugindef self.included(base)base.extend(ClassMethods)endclass Configattr_reader :modelattr_reader :model_iddef initialize(model_id)@model_id = model_id@model = model_id.to_s.camelize.constantizeenddef model_name@model_id.to_sendendmodule ClassMethodsdef my_plugin(model_id = nil)model_id = self.to_s.split('::').last.sub(/Controller$/, '').pluralize.singularize.underscore unless model_id@my_plugin_config = MyPlugin::Config.new(model_id)include MyPlugin::InstanceMethodsenddef my_plugin_config@my_plugin_config || self.superclass.instance_variable_get('@my_plugin_config')endendmodule InstanceMethodsdef export_to_xmldata = self.class.my_plugin_config.model.find(:all, :order => 'published_date', :conditions => conditions_for_collection)send_data data.to_xml, :type => 'text/xml; charset=UTF-8;',:disposition => "attachment; filename=#{self.class.my_plugin_config.model_name.pluralize}.xml"end# 在controller中覆盖此method,写入满足的条件def conditions_for_collectionendendend
OK了吗? No No No 还要让rails加载plugin,在rails应用启动时,会到vendor/plugins目录查找所有plugin,并执行其中的init.rb
那么就edit init.rb
- ActionController::Base.class_eval do
- include MyPlugin
- end
ActionController::Base.class_eval doinclude MyPlugin
end
或edit这样:
- require 'my_plugin'
- ActionController::Base.send :include, MyPlugin
require 'my_plugin'
ActionController::Base.send :include, MyPlugin
最后就按上面的需求写入controller了