Pārlūkot izejas kodu

Refactor Drop classes.

Not alone EventDrop but all subclasses now take a hash of "locals" which
could be referenced in interpolation.  This will make it easier for
Agent classes to add custom "locals" for use in interpolation.
Akinori MUSHA 10 gadi atpakaļ
vecāks
revīzija
a93bb2674e
4 mainītis faili ar 65 papildinājumiem un 30 dzēšanām
  1. 42 1
      app/concerns/liquid_droppable.rb
  2. 2 12
      app/models/agent.rb
  3. 12 17
      app/models/event.rb
  4. 9 0
      spec/models/event_spec.rb

+ 42 - 1
app/concerns/liquid_droppable.rb

@@ -1,9 +1,50 @@
 module LiquidDroppable
   extend ActiveSupport::Concern
 
+  # In subclasses of this base class, "locals" take precedence over
+  # methods.
   class Drop < Liquid::Drop
-    def initialize(object)
+    class << self
+      def inherited(subclass)
+        class << subclass
+          attr_reader :drop_methods
+
+          # Make all public methods private so that #before_method
+          # catches everything.
+          def drop_methods!
+            return if @drop_methods
+
+            @drop_methods = Set.new
+
+            (public_instance_methods - Drop.public_instance_methods).each { |name|
+              @drop_methods << name.to_s
+              private name
+            }
+          end
+        end
+      end
+    end
+
+    def initialize(object, locals = nil)
+      self.class.drop_methods!
+
       @object = object
+      @locals = locals || {}
+    end
+
+    def before_method(name)
+      if @locals.include?(name)
+        @locals[name]
+      elsif self.class.drop_methods.include?(name)
+        __send__(name)
+      end
+    end
+
+    def each
+      return to_enum(__method__) unless block_given?
+      self.class.drop_methods.each { |name|
+        yield [name, __send__(name)]
+      }
     end
   end
 

+ 2 - 12
app/models/agent.rb

@@ -391,7 +391,7 @@ class AgentDrop
     @object.short_type
   end
 
-  METHODS = [
+  [
     :name,
     :type,
     :options,
@@ -402,19 +402,9 @@ class AgentDrop
     :disabled,
     :keep_events_for,
     :propagate_immediately,
-  ]
-
-  METHODS.each { |attr|
+  ].each { |attr|
     define_method(attr) {
       @object.__send__(attr)
     } unless method_defined?(attr)
   }
-
-  def each(&block)
-    return to_enum(__method__) unless block
-
-    METHODS.each { |attr|
-      yield [attr, __sent__(attr)]
-    }
-  end
 end

+ 12 - 17
app/models/event.rb

@@ -44,26 +44,21 @@ class Event < ActiveRecord::Base
 end
 
 class EventDrop
-  def initialize(event, payload = event.payload)
-    super(event)
-    @payload = payload
-  end
-
-  def before_method(key)
-    if @payload.key?(key)
-      @payload[key]
-    else
-      case key
-      when 'agent'
-        @object.agent
-      when 'created_at'
-        @object.created_at
-      end
-    end
+  def initialize(object, locals = nil)
+    locals ||= object.payload
+    super
   end
 
   def each(&block)
     return to_enum(__method__) unless block
-    @payload.each(&block)
+    @locals.each(&block)
+  end
+
+  def agent
+    @object.agent
+  end
+
+  def created_at
+    @object.created_at
   end
 end

+ 9 - 0
spec/models/event_spec.rb

@@ -102,6 +102,15 @@ describe EventDrop do
     interpolate(t, @event).should eq('some title: http://some.site.example.org/')
   end
 
+  it 'should use created_at from the payload if it exists' do
+    created_at = @event.created_at - 86400
+    # Avoid timezone issue by using %s
+    @event.payload['created_at'] = created_at.strftime("%s")
+    @event.save!
+    t = '{{created_at | date:"%s" }}'
+    interpolate(t, @event).should eq(created_at.strftime("%s"))
+  end
+
   it 'should be iteratable' do
     # to_liquid returns self
     t = "{% for pair in to_liquid %}{{pair | join:':' }}\n{% endfor %}"