Class: ActiveModel::AttributeSet::Query

Inherits:
BasicObject
Defined in:
lib/attribute-filters/attribute_set_query.rb

Overview

This class contains proxy methods used to interact with AttributeSet instances. It’s responsible for all of the DSL magic that allows sweet constructs like:

some_attribute_set.all.present?

Direct Known Subclasses

AttrQuery

Instance Method Summary collapse

Constructor Details

#initialize(set_object, am_object) ⇒ Query

Creates new query object.

Parameters:

  • set_object (AttributeSet)

    attribute set for which the query will be made

  • am_object (Object)

    model object which has access to attributes (may be an instance of ActiveRecord or similar)



22
23
24
25
26
# File 'lib/attribute-filters/attribute_set_query.rb', line 22

def initialize(set_object, am_object)
  @set_object = set_object
  @am_object = am_object
  @next_method = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_sym, *args) { ... } ⇒ Object

This is a proxy method that causes some calls to be queued to for the next call. Is allows to create semi-natural syntax when querying attribute sets.

When method_sym is set to :all or :any then new query is created and the next method given in chain is passed to each element of the set with question mark added to its name.

Example:

some_attribute_set.all.present?

is converted to

some_attribute_set.all? { |atr| atr.present? }

When method_sym is set to list or show then new query is constructed and the next method given in chain is passed to any element collected by applying select to set.

Example:

some_attribute_set.list.present?

is converted to

some_attribute_set.select { |atr| atr.present? }

Parameters:

  • method_sym (Symbol, String)

    name of method that will be queued or called on attribute set

  • args (Array)

    optional arguments to be passed to a method call or to a queued method call

Yields:

  • optional block to be passed to a method call or to a queued method call

Returns:

  • (Object)

    the returned value is passed back from called method



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/attribute-filters/attribute_set_query.rb', line 54

def method_missing(method_sym, *args, &block)
  case method_sym.to_sym
  when :are, :is, :be, :should
    return self
  end
  if @next_method.nil?
    case method_sym.to_sym
    when :all, :any, :none, :one
      ::ActiveModel::AttributeSet::Query.new(@set_object, @am_object).   # new obj. == thread-safe
        next_step(method_sym.to_s << "?", args, block)
    when :list, :show
      ::ActiveModel::AttributeSet::Query.new(@set_object, @am_object).
        next_step(:select, args, block)
    else
      r = @set_object.method(method_sym).call(*args, &block)
      return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
      ::ActiveModel::AttributeSet::Query.new(r, @am_object)
    end
  else
    m, args, block = @next_method
    @next_method = nil
    r = @set_object.method(m).call { |a| @am_object[a].method(method_sym).call(*args, &block) }
    return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
    ::ActiveModel::AttributeSet::Query.new(r, @am_object)
  end
end

Instance Method Details

#next_step(method_name, args, block) ⇒ AttributeSet (protected)

Queues any method of the given name to be called when next query (method call) is made.

Parameters:

  • method_name (Symbol)

    name of a method to be called on next call to any query method

  • args (Array)

    arguments to be passed to the called method

  • block (Proc)

    code block to be passed to the called method

Returns:



106
107
108
109
# File 'lib/attribute-filters/attribute_set_query.rb', line 106

def next_step(method_name, args, block)
  @next_method = [method_name, args, block]
  return self
end