Class: Liquor::Drop

Inherits:
Object
  • Object
show all
Includes:
External
Defined in:
lib/liquor/drop/drop.rb

Defined Under Namespace

Classes: Scope

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from External

included, #liquor_send

Constructor Details

#initialize(source) ⇒ Drop


18
19
20
# File 'lib/liquor/drop/drop.rb', line 18

def initialize(source)
  @source = source
end

Instance Attribute Details

#sourceObject (readonly)

Returns the value of attribute source


7
8
9
# File 'lib/liquor/drop/drop.rb', line 7

def source
  @source
end

Class Method Details

.attributes(*attrs) ⇒ Object


22
23
24
25
26
27
28
29
# File 'lib/liquor/drop/drop.rb', line 22

def self.attributes(*attrs)
  attrs.each do |attr|
    define_method(attr) {
      @source.send(attr)
    }
    export attr
  end
end

.belongs_to(name, options = {}) ⇒ Object


105
106
107
# File 'lib/liquor/drop/drop.rb', line 105

def self.belongs_to(name, options={})
  define_singular_association_accessor(name, options)
end

.check_singular_condition(object, options) ⇒ Object


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/liquor/drop/drop.rb', line 85

def self.check_singular_condition(object, options)
  execute = lambda do |object, condition|
    if condition.is_a? Symbol
      object.send(condition)
    elsif condition.respond_to? :call
      condition.(object)
    else
      raise ArgumentError, "Invalid condition type #{condition.class}"
    end
  end

  if options[:if]
    execute.(object, options[:if])
  elsif options[:unless]
    !execute.(object, options[:unless])
  else
    true
  end
end

.define_singular_association_accessor(name, options = {}) ⇒ Object


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/liquor/drop/drop.rb', line 60

def self.define_singular_association_accessor(name, options={})
  if options.has_key?(:if) && options.has_key?(:unless)
    raise ArgumentError, "It is pointless to pass both :if and :unless conditions to has_one or belongs_to"
  end

  unsupported_options = (options.keys - [:if, :unless])
  if unsupported_options.any?
    raise ArgumentError, "Unsupported options #{unsupported_options.join(", ")}"
  end

  define_method(name) {
    value = @source.send(name)

    if self.class.check_singular_condition(value, options)
      if value.nil?
        nil
      else
        DropDelegation.wrap_element(value)
      end
    end
  }

  export name
end

.has_many(name, options = {}) ⇒ Object


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/liquor/drop/drop.rb', line 113

def self.has_many(name, options={})
  unsupported_options = (options.keys - [:scope, :include])
  if unsupported_options.any?
    raise ArgumentError, "Unsupported options #{unsupported_options.join(", ")}"
  end

  define_method(name) {
    value = @source.send(name)

    if options[:scope]
      # Sequentally apply each symbol from options[:scope]
      # to the current scope, starting from `value' and using
      # each result as current scope for the next operation.
      value = Array(options[:scope]).reduce(value, &:send)
    end

    if options[:include]
      Array(options[:include]).each do |collection|
        value = value.includes(collection)
      end
    end

    DropDelegation.wrap_scope(value, value.klass)
  }

  export name
end

.has_one(name, options = {}) ⇒ Object


109
110
111
# File 'lib/liquor/drop/drop.rb', line 109

def self.has_one(name, options={})
  define_singular_association_accessor(name, options)
end

.inherited(klass) ⇒ Object


9
10
11
12
13
14
15
16
# File 'lib/liquor/drop/drop.rb', line 9

def self.inherited(klass)
  klass.instance_exec do
    const_set :Scope, Class.new(::Liquor::Drop::Scope)
    const_get(:Scope).instance_exec do
      export # refresh liquor_exports
    end
  end
end

.scopes(*scopes) ⇒ Object


31
32
33
34
35
36
37
38
39
40
41
# File 'lib/liquor/drop/drop.rb', line 31

def self.scopes(*scopes)
  const_get(:Scope).instance_exec do
    scopes.each do |scope|
      define_method(scope) { |*args|
        args = Drop.unwrap_scope_arguments(args)
        DropDelegation.wrap_scope @source.send(scope, *args)
      }
      export scope
    end
  end
end

.unwrap_scope_arguments(args) ⇒ Object


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/liquor/drop/drop.rb', line 43

def self.unwrap_scope_arguments(args)
  args.map do |arg|
    case arg
    when Drop
      arg.id
    when Drop::Scope
      unwrap_scope_arguments(arg.to_a)
    when Array
      unwrap_scope_arguments(arg)
    when Hash
      Hash[arg.keys.zip(unwrap_scope_arguments(arg.values))]
    else
      arg
    end
  end
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?


146
147
148
149
150
151
152
# File 'lib/liquor/drop/drop.rb', line 146

def ==(other)
  if other.is_a? Liquor::Drop
    self.source == other.source
  else
    other == self
  end
end

#entityObject


141
142
143
# File 'lib/liquor/drop/drop.rb', line 141

def entity
  @source.class.model_name.to_s
end

#hashObject


156
157
158
# File 'lib/liquor/drop/drop.rb', line 156

def hash
  @source.hash
end

#to_dropObject


160
161
162
# File 'lib/liquor/drop/drop.rb', line 160

def to_drop
  self
end