Search code examples
ruby-on-railsactiverecordactivesupport-concern

Rails: Concern with before_filter type of method


I am just getting my hands on Concerns in Rails and try to implement a simple logging for ActiveRecord classes. In there I want to define the field that should go into the log and have the log written automatically after save.

What I have is this:

#logable.rb (the concern)
module Logable
  extend ActiveSupport::Concern

  @field = nil
  module ClassMethods
    def set_log_field(field)
      @feild = field
    end
  end

  def print_log
    p "LOGGING: #{self[@index.to_s]}"
  end
end


#houses.rb (the model using the concern)
class House < ActiveRecord::Base
  include Logable
  after_save :print_log
  set_log_field :id
end

Unfortunately the call to set_log_field does not have an effect - or rather the given value does not make it to print_log. What am I doing wrong?

Thanks for your help!


Solution

  • You probably mean this (btw, why not Loggable?):

    # logable.rb
    module Logable
      extend ActiveSupport::Concern
    
      # Here we define class-level methods.
      # Note, that @field, defined here cannot be referenced as @field from
      # instance (it's class level!).
      # Note also, in Ruby there is no need to declare @field in the body of a class/module.
      class_methods do
        def set_log_field(field)
          @field = field
        end
    
        def log_field
          @field
        end
      end
    
      # Here we define instance methods.
      # In order to access class level method (log_field), we use self.class.
      included do
        def print_log
          p "LOGGING: #{self.class.log_field}"
        end
      end
    end
    

    Update You also asked about what's the difference between methods in included block and those within method body.

    To make a short resume there is seemingly no difference. In very good approximation you can consider them the same. The only minor difference is in dependency management. Great illustration of it is given in the end of ActiveSupport::Concern documentation. It worth reading, take a look!