Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: callbacks from module

I try to do this:

app/models/my_model.rb:

class MyModel <  ActiveRecord::Base
  include MyModule
  ...
end

lib/my_module.rb:

module MyModule
  before_destroy :my_func    #!

  def my_func
    ...
  end
end

but I get an error:

undefined method `before_destroy' for MyModule:Module

How can I correct it.

Also I'm new to ruby. What type has these "attributes": before_destroy, validates, has_many? Are they variables or methods or what? Thanks

like image 405
welldan97 Avatar asked Mar 06 '11 10:03

welldan97


People also ask

What are callbacks in rails?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.

What is controller callback in rails?

Abstract Controller Callbacks Abstract Controller provides hooks during the life cycle of a controller action. Callbacks allow you to trigger logic during this cycle. Available callbacks are: after_action. append_after_action.

What is the difference between delete and destroy in rails?

Rails Delete operation using delete method Unlike the destroy method, with delete, you can remove a record directly from the database. Any dependencies to other records in the model are not taken into account. The method delete only deletes that one row in the database and nothing else.

What are observers in Rails?

Observer is a behavioral design pattern that allows some objects to notify other objects about changes in their state. The Observer pattern provides a way to subscribe and unsubscribe to and from these events for any object that implements a subscriber interface.


1 Answers

before_destroy, validates, etc. are not attributes or anything like that. These are method calls.

In ruby, the body of a class is all executable code, meaning that each line of the class body is executed by the interpeter just like a method body would.

before_destroy :my_func is a usual ruby method call. The method that gets called is before_destroy, and it receives a symbol :my_func as an argument. This method is looked up in the class (or module) in the scope of which it is called.

So moving on to your question, I think now you should understand that when the interpreter loads your module

module MyModule
  before_destroy :my_func    #!

  def my_func
    ...
  end
end

it starts executing its body and searches for the method before_destroy in this module and cannot find one. What you want to do is call this method not on the module, but rather on the class where the module is included. For that we have a common idiom using the Module#included method:

module MyModule
  module InstanceMethods
    def my_func
      ...
    end
  end

  def self.included(base)
    base.send :include, InstanceMethods
    base.before_destroy :my_func
  end
end
like image 83
alex.zherdev Avatar answered Oct 13 '22 02:10

alex.zherdev