Class: ActiveFedora::Associations::Association

Inherits:
Object
  • Object
show all
Defined in:
lib/active_fedora/associations/association.rb

Overview

This is the root class of all associations:

Association
  BelongsToAssociation
  AssociationCollection
    HasManyAssociation

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner, reflection) ⇒ Association

Returns a new instance of Association.



16
17
18
19
20
21
22
# File 'lib/active_fedora/associations/association.rb', line 16

def initialize(owner, reflection)
  reflection.check_validity!
  @owner = owner
  @reflection = reflection
  reset
  reset_scope
end

Instance Attribute Details

#inversedObject

Returns the value of attribute inversed.



13
14
15
# File 'lib/active_fedora/associations/association.rb', line 13

def inversed
  @inversed
end

#ownerObject (readonly)

Returns the value of attribute owner.



12
13
14
# File 'lib/active_fedora/associations/association.rb', line 12

def owner
  @owner
end

#reflectionObject (readonly)

Returns the value of attribute reflection.



12
13
14
# File 'lib/active_fedora/associations/association.rb', line 12

def reflection
  @reflection
end

#targetObject

Returns the value of attribute target.



12
13
14
# File 'lib/active_fedora/associations/association.rb', line 12

def target
  @target
end

Instance Method Details

#association_scopeObject

The scope for this association.

Note that the association_scope is merged into the target_scope only when the scope method is called. This is because at that point the call may be surrounded by scope.scoping { … } or with_scope { … } etc, which affects the scope which actually gets built.



78
79
80
# File 'lib/active_fedora/associations/association.rb', line 78

def association_scope
  @association_scope ||= AssociationScope.scope(self) if klass
end

#initialize_attributes(record, except_from_scope_attributes = nil) ⇒ Object

:nodoc:



122
123
124
125
126
127
128
129
130
# File 'lib/active_fedora/associations/association.rb', line 122

def initialize_attributes(record, except_from_scope_attributes = nil) # :nodoc:
  except_from_scope_attributes ||= {}
  skip_assign = [reflection.foreign_key].compact
  assigned_keys = record.changed
  assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
  attributes = create_scope.except(*(assigned_keys - skip_assign))
  record.assign_attributes(attributes)
  set_inverse_instance(record)
end

#load_targetObject

Loads the target if needed and returns it.

This method is abstract in the sense that it relies on find_target, which is expected to be provided by descendants.

If the target is already loaded it is just returned. Thus, you can call load_target unconditionally to get the target.

ActiveFedora::ObjectNotFoundError is rescued within the method, and it is not reraised. The proxy is reset and nil is the return value.



114
115
116
117
118
119
120
# File 'lib/active_fedora/associations/association.rb', line 114

def load_target
  @target = find_target if (@stale_state && stale_target?) || find_target?
  loaded! unless loaded?
  target
rescue ActiveFedora::ObjectNotFoundError
  reset
end

#loaded!Object

Asserts the target has been loaded setting the loaded flag to true.



46
47
48
49
50
# File 'lib/active_fedora/associations/association.rb', line 46

def loaded!
  @loaded = true
  @stale_state = stale_state
  @inversed = false
end

#loaded?Boolean

Has the target been already loaded?

Returns:

  • (Boolean)


41
42
43
# File 'lib/active_fedora/associations/association.rb', line 41

def loaded?
  @loaded
end

#reloadObject

Reloads the target and returns self on success.



33
34
35
36
37
38
# File 'lib/active_fedora/associations/association.rb', line 33

def reload
  reset
  reset_scope
  load_target
  self unless @target.nil?
end

#resetObject

Resets the loaded flag to false and sets the target to nil.



25
26
27
28
29
30
# File 'lib/active_fedora/associations/association.rb', line 25

def reset
  @loaded = false
  @target = nil
  @stale_state = nil
  @inversed = false
end

#reset_scopeObject



82
83
84
# File 'lib/active_fedora/associations/association.rb', line 82

def reset_scope
  @association_scope = nil
end

#scopeObject



68
69
70
# File 'lib/active_fedora/associations/association.rb', line 68

def scope
  target_scope.merge(association_scope)
end

#set_inverse_instance(record) ⇒ Object

Set the inverse association, if possible



87
88
89
90
91
92
93
94
95
96
# File 'lib/active_fedora/associations/association.rb', line 87

def set_inverse_instance(record)
  return unless record && invertible_for?(record)
  inverse = record.association(inverse_reflection_for(record).name.to_sym)
  if inverse.is_a? ActiveFedora::Associations::HasAndBelongsToManyAssociation
    inverse.target << owner
  else
    inverse.target = owner
  end
  inverse.inversed = true
end

#stale_target?Boolean

The target is stale if the target no longer points to the record(s) that the relevant foreign_key(s) refers to. If stale, the association accessor method on the owner will reload the target. It’s up to subclasses to implement the state_state method if relevant.

Note that if the target has not been loaded, it is not considered stale.

Returns:

  • (Boolean)


58
59
60
# File 'lib/active_fedora/associations/association.rb', line 58

def stale_target?
  !inversed && loaded? && @stale_state != stale_state
end

#target_scopeObject

Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the through association’s scope)



100
101
102
# File 'lib/active_fedora/associations/association.rb', line 100

def target_scope
  klass.all
end