2014-11-24 102 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 

默認的是,這猴子補丁實在是太醜了。但它的工作。