2014-11-24 79 views
0

我试图使一个rake任务猴子补丁的Rails 3.2,我想在创业板实现这个(让我们叫他my_plugin)猴子补丁轨3.2 rake任务

例如,databases.rake有以下内容:

db_namespace = namespace :db do 
    # ... 
    # desc "Retrieves the charset for the current environment's database" 
    task :charset => [:environment, :load_config] do 
    config = ActiveRecord::Base.configurations[Rails.env] 
    case config['adapter'] 
    when /mysql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.charset 
    when /postgresql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
    when /sqlite/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
    else 
     $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' 
    end 
    end 
    # ... 
end 

而且我想通过我的替换默认的行为:

db_namespace = namespace :db do 
    # ... 
    # desc "Retrieves the charset for the current environment's database" 
    task :charset => [:environment, :load_config] do 
    puts 'Here is my gem override' 
    config = ActiveRecord::Base.configurations[Rails.env] 
    case config['adapter'] 
    when /mysql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.charset 
    when /postgresql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
    when /sqlite/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
    when /OTHER_ADAPTER/ 
     puts 'OTHER_ADAPTER_ENCODING' 
    else 
     $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' 
    end 
    end 
    # ... 
end 

所以我写了下面的代码在my_plugin:

文件:my_plugin.rb

if defined?(Rake) 
    Rake::TaskManager.class_eval do 
    def replace_task(task_name, task_scope) 
     scope_backup = @scope 
     @scope = Rake::Scope.new(task_scope) 
     task_name_full = @scope.path_with_task_name(task_name) 
     @tasks[task_name_full] = yield 
     @scope = scope_backup 
    end 
    end 

    Rake.application.replace_task('charset', 'db') do 
    task :charset => [:environment, :load_config] do 
     puts 'Here is my gem override' 
     config = ActiveRecord::Base.configurations[Rails.env] 
     case config['adapter'] 
     when /mysql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.charset 
     when /postgresql/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
     when /redshift/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
     when /sqlite/ 
     ActiveRecord::Base.establish_connection(config) 
     puts ActiveRecord::Base.connection.encoding 
     when /OTHER_ADAPTER/ 
     puts 'OTHER_ADAPTER_ENCODING' 
     else 
     $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' 
     end 
    end 
    end 
end 

但是,当我打电话束的exec耙分贝:字符集:

** Invoke db:charset (first_time) 
** Invoke environment (first_time) 
** Execute environment 
** Invoke db:load_config (first_time) 
** Execute db:load_config 
** Execute db:charset 
UTF8          -> First call from rails default method 
Here is my gem override 
UTF8          -> Second call, my monkey patch 
Shutdown completed cleanly 

为什么有第一个电话?

回答

0

好吧,我找到一种方法,使工作得益于这个帖子:How to monkey patch a rake task shipped with Rails?

所以我的代码是:

Rake::TaskManager.class_eval do 
    def replace_task(task_name, task_scope) 
    scope_backup = @scope 
    @scope = Rake::Scope.new(task_scope) 
    task_name_full = @scope.path_with_task_name(task_name) 
    @tasks[task_name_full].clear 
    @tasks[task_name_full] = yield 
    @scope = scope_backup 
    end 
end 

默认的是,这猴子补丁实在是太丑了。但它的工作。