2015-11-21 2 views
1

Как я могу переопределить одну или несколько строк кода в родительском классе ruby? Например: У меня есть Rails класс контроллера с методом create:Ruby partically override метод родительского класса

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) Вам нужно будет добавить переменную, указывающую, был ли блок блоком * before * или * after *. 3) Суперкласс должен был пропустить шаг 'resource.save'', если block_given? ' – 7stud

Смежные вопросы