Roman
Roman

Reputation: 363

Ruby partically override parent class method

How can I override one or more lines of code in ruby parent class? For example: I have Rails controller class with method create:

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

And I have another controller, child of this controller

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

How can I achieve this? I tried this (generic controller):

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

But what if I want to pass more than one block? For example if I want to make callbacks :after_init, :before_save, :after_save and so on?

Upvotes: 1

Views: 2619

Answers (1)

7stud
7stud

Reputation: 48609

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

But what if I want to pass more than one block? For example if I want to make callbacks :after_init, :before_save, :after_save and so on

You need to pass the blocks to the superclass method outside your create() method:

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

Upvotes: 1

Related Questions