2015-11-21 57 views
1

如何重写ruby父类中的一行或多行代码? 例如:我有方法create Rails的控制器类:Ruby特别重写父类方法

class GenericController < ApplicationController 
def create 
    @resource = SomeClass.new 
    if @resource.save 
     ... 
    else 
     ... 
    end 
    end 
end 

而且我还有一个控制器,孩子该控制器的

class ChildController < GenericController 
    def create 
    super do 
     # HERE I WANT TO DO SOME ACTIONS BEFORE SAVE. 
    end 
    end 
end 

我怎样才能做到这一点?我试过这个(通用控制器):

def create 
    @resource = SomeClass.new 
    yield if block_given? 
    if @resource.save 
     ... 
    end 
    end 

但是如果我想通过多个块呢?例如,如果我想做回调:after_init,:before_save,:after_save等?

回答

1
def create 
    super do 
     # HERE I WANT TO DO SOME ACTIONS BEFORE SAVE. 
    end 
    end 

但是,如果我想传递一个街区更是什么?例如,如果我想 进行回调:after_init,:before_save,:after_save的等

您需要的块传递给超类方法create()方法:

class Dog < GenericController 
    before_save do 
    puts 'before1' 
    end 

    after_save do 
    puts 'after1' 
    end 

    before_save do 
    puts 'before2' 
    end 

    def create 
    super 
    end 

end 

class GenericController 
    class <<self 
    attr_accessor :before, :after 

    def before_save(&block) 
     @before << block 
    end 

    def after_save(&block) 
     @after << block 
    end 
    end 

    def self.inherited(subclass) 
    subclass.instance_variable_set(:@before, []) 
    subclass.instance_variable_set(:@after, []) 
    end 

    def create 

    self.class.before.each do |proc| 
     proc.call 
    end 

    puts 'saving resource...' 
    #@resource.save 

    self.class.after.each do |proc| 
     proc.call 
    end 

    end 

end 

Dog.new.create 

--output:-- 
before1 
before2 
saving resource... 
after1 
+0

好的,但是如果我想添加一些代码如果资源创建后呢?块将执行两次。 – Roman

+0

谢谢=)这就是我想要的=) – Roman

+0

@Roman,如果你用你的创建方法传递块:1)你将不得不多次调用create()。 2)您必须添加一个变量,指示该块在*块之后是*之前的*还是*。 3)超级类将不得不跳过'resource.save'步骤'if block_given?' – 7stud