Class: SimpleMapper::Associations::Association

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_mapper/default_plugins/associations.rb

Overview

Association is a completely independent class that is designed to use standard methods in your model in order to bring associations to that model class. The following assumptions are made about the logic of the concept of associations:

  1. object -> associated_objects: associations are ALWAYS managed on a basis of one object being associated with other objects. This means that you can specify association attributes that are based on the primary object, the associated (foreign) object, or both; but you can only ‘scope’ the finding of associated objects based on foreign attributes.

  2. primary, foreign, and scope: primary refers to the object in hand, foreign refers to an associated object, and scope refers to a subset of the associated objects. Primary options govern the association-related attributes on the primary object, Foreign options govern the association-related attributes on the foreign object, and Scope options are simply extra unrelated attributes used to find a smaller group within the otherwise associatable objects.

  3. Model.all: the ‘all’ method is called on your Model in order to find associated records, and is passed the aggregated finder_options.

Todo: Add in the amazing :through option

Defined Under Namespace

Classes: Instance, Set

Constant Summary collapse

OPTIONS =
[:class_name]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, type, options = {}, object = nil) ⇒ Association

Returns a new instance of Association.



106
107
108
109
110
111
# File 'lib/simple_mapper/default_plugins/associations.rb', line 106

def initialize(klass, type, options={}, object=nil)
  @klass = klass
  @type = type
  @options = options
  @object = object; @procs_run = 0
end

Instance Attribute Details

#typeObject (readonly)

Returns the value of attribute type.



104
105
106
# File 'lib/simple_mapper/default_plugins/associations.rb', line 104

def type
  @type
end

Instance Method Details

#act_asObject



220
221
222
# File 'lib/simple_mapper/default_plugins/associations.rb', line 220

def act_as
  @act_as || @mirrored_association_name
end

#apply_to(object) ⇒ Object

Ties the association definition with a primary object. This will allow for any options based on the object itself to be determined before running the query for associated objects.



243
244
245
246
247
248
# File 'lib/simple_mapper/default_plugins/associations.rb', line 243

def apply_to(object)
  applied = dup
  applied.instance_variable_set(:@object, object)
  applied.instance_variable_set(:@procs_run, 0)
  applied
end

#associated_klassObject

Returns the class associated, if it is found.



191
192
193
# File 'lib/simple_mapper/default_plugins/associations.rb', line 191

def associated_klass
  @associated_klass ||= Object.module_eval("::#{Inflector.camelize(@options[:class_name].to_s)}", __FILE__, __LINE__)
end

#finder_options(run_dynamic = true) ⇒ Object

The current finder_options used for finding associated objects. It simply combines primary, foreign, and scope. This is public only for debugging purposes.



233
234
235
236
237
238
# File 'lib/simple_mapper/default_plugins/associations.rb', line 233

def finder_options(run_dynamic=true)
  primary_options(run_dynamic).merge(foreign_options(run_dynamic)).merge(foreign_scope(run_dynamic)).inject({}) do |h,(k,v)|
    h[k] = (@object && v.is_a?(Symbol) && @object.respond_to?(v)) ? @object.send(v) : v
    h
  end
end

#foreign?Boolean

Returns:

  • (Boolean)


227
228
229
# File 'lib/simple_mapper/default_plugins/associations.rb', line 227

def foreign?
  !foreign_options.empty?
end

#foreign_options(run_dynamic = true) ⇒ Object



179
180
181
182
183
# File 'lib/simple_mapper/default_plugins/associations.rb', line 179

def foreign_options(run_dynamic=true)
  @foreign_options ||= {}
  run_dynamic_procs if run_dynamic
  @foreign_options
end

#foreign_scope(run_dynamic = true) ⇒ Object



184
185
186
187
188
# File 'lib/simple_mapper/default_plugins/associations.rb', line 184

def foreign_scope(run_dynamic=true)
  @foreign_scope ||= {}
  run_dynamic_procs if run_dynamic
  @foreign_scope
end

#inspectObject

# # # # # # # # # # # # # # # # # # # # # # # # # Accessor Methods



169
170
171
172
# File 'lib/simple_mapper/default_plugins/associations.rb', line 169

def inspect # :nodoc:
  run_dynamic_procs
  super
end

#merge(other) ⇒ Object

This is a powerful method that merges two associations into one new association.

Raises:

  • (ArgumentError)


251
252
253
254
255
# File 'lib/simple_mapper/default_plugins/associations.rb', line 251

def merge(other)
  raise ArgumentError, "must be an association definition object" unless other.is_a?(SimpleMapper::Associations::Association)
  # self.class.new(@klass, :many)
  other
end

#mirrored_associationObject



212
213
214
215
216
217
218
# File 'lib/simple_mapper/default_plugins/associations.rb', line 212

def mirrored_association
  return nil unless @mirrored_association_name || @act_as
  @mirrored_association || begin
    @procs_run = 0 # Just another place to reset this -- a dynamic proc could rely on a mirrored_association, after all...
    @mirrored_association = associated_klass.associations[@mirrored_association_name || @act_as]
  end
end

#mirrored_association_nameObject



208
209
210
# File 'lib/simple_mapper/default_plugins/associations.rb', line 208

def mirrored_association_name
  @mirrored_association_name || @act_as
end

#primary?Boolean

Returns:

  • (Boolean)


224
225
226
# File 'lib/simple_mapper/default_plugins/associations.rb', line 224

def primary?
  !primary_options.empty?
end

#primary_options(run_dynamic = true) ⇒ Object



174
175
176
177
178
# File 'lib/simple_mapper/default_plugins/associations.rb', line 174

def primary_options(run_dynamic=true)
  @primary_options ||= {}
  run_dynamic_procs if run_dynamic
  @primary_options
end

#set(instance = nil) ⇒ Object

This is a very key method that creates an association set based on an object and the association. If you call it with an instance, it will dup the association for the set; If this association is already applied to an object, it creates an association set.



198
199
200
201
202
203
204
205
206
# File 'lib/simple_mapper/default_plugins/associations.rb', line 198

def set(instance=nil)
  if instance
    apply_to(instance).set
  elsif @object
    @type == :many ? Set.new(@object, self) : Instance.new(@object, self)
  else
    raise ArgumentError, "must include instance"
  end
end