Class: OriginRelationship

Inherits:
ApplicationRecord show all
Includes:
Housekeeping, Shared::IsData, Shared::PolymorphicAnnotator
Defined in:
app/models/origin_relationship.rb

Overview

An OriginRelationship asserts that one object is derived_from another.

The old object is the source_of or origin_of the new object. The new object originates_from the old_object.

Currently these combinations are planned (* not implemented):

old_object / new_object

  • field_observation / collection_object

collection_object / collection_object collection_object / extract

  • collection_object / part_of (anatomy)

  • part_of / part_of

  • part_of / extract

extract / extract extract / sequence sequence / sequence

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Shared::PolymorphicAnnotator

#annotated_object_is_persisted?

Methods included from Shared::IsData

#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_in_use?, #similar

Methods included from Housekeeping

#has_polymorphic_relationship?

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#new_object_idInteger

Returns id of the new (original) object.

Returns:

  • (Integer)

    id of the new (original) object



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

#new_object_typeInteger

Returns type of the new (original) object.

Returns:

  • (Integer)

    type of the new (original) object



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

#old_object_idInteger

Returns id of the old (original) object.

Returns:

  • (Integer)

    id of the old (original) object



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

#old_object_typeInteger

Returns type of the old (original) object.

Returns:

  • (Integer)

    type of the old (original) object



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

#positionInteger

Returns order relative to old object.

Returns:

  • (Integer)

    order relative to old object



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

#project_idInteger

Returns the project ID.

Returns:

  • (Integer)

    the project ID



44
45
46
47
48
49
50
51
52
53
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
# File 'app/models/origin_relationship.rb', line 44

class OriginRelationship < ApplicationRecord
  include Housekeeping
  include Shared::IsData
  include Shared::PolymorphicAnnotator

  polymorphic_annotates('old_object', presence_validate: false)
  polymorphic_annotates('new_object', presence_validate: false)

  # Used for what?
  acts_as_list scope: [:project_id, :old_object_id, :old_object_type]

  belongs_to :old_object, polymorphic: true, inverse_of: :origin_relationships
  belongs_to :new_object, polymorphic: true, inverse_of: :related_origin_relationships

  # Abort destroy if any old or new object objects.
  before_destroy :poll_old_and_new_objects_for_destroy

  # The two validations, and the inclusion of the Shared::OriginRelationship code
  # ensure that new/old objects are indeed ones that are allowed (otherwise we will get Raises, which means the UI is messed up)
  validates_presence_of :new_object
  validates_presence_of :old_object

  # Abort create if any old or new object objects.
  validate :poll_old_and_new_objects_for_create, on: :create
  validate :old_object_responds
  validate :new_object_responds
  validate :pairing_is_allowed, unless: -> {!errors.empty?}

  validate :not_a_clone

  private

  def old_object_responds
    errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
  end

  def new_object_responds
    errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
  end

  def new_object_can_be_derived_from(klass)
    new_object.respond_to?(:valid_old_object_classes) &&
      new_object.valid_old_object_classes.include?(klass)
  end

  def old_object_can_be_origin_of(klass)
    old_object.respond_to?(:valid_new_object_classes) &&
      old_object.valid_new_object_classes.include?(klass)
  end

  def pairing_is_allowed
    errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

    errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
  end

  def not_a_clone
    if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
      errors.add(:old_object, 'objects can not be cloned (related to each other)')
    end
  end

  def poll_old_and_new_objects_for_create
    if old_object.respond_to?(:allow_origin_relationship_create?) &&
       !old_object.allow_origin_relationship_create?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
    end

    if new_object.respond_to?(:allow_origin_relationship_create?) &&
       !new_object.allow_origin_relationship_create?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
    end
  end

  def poll_old_and_new_objects_for_destroy
    if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !old_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end

    if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
       !new_object.allow_origin_relationship_destroy?(self)
      errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
      old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
      new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

      throw(:abort)
    end
  end
end

Instance Method Details

#new_object_can_be_derived_from(klass) ⇒ Object (private)



84
85
86
87
# File 'app/models/origin_relationship.rb', line 84

def new_object_can_be_derived_from(klass)
  new_object.respond_to?(:valid_old_object_classes) &&
    new_object.valid_old_object_classes.include?(klass)
end

#new_object_respondsObject (private)



80
81
82
# File 'app/models/origin_relationship.rb', line 80

def new_object_responds
  errors.add(:new_object, "#{new_object.class.name} is not a legal part of an origin relationship") if !(new_object.class < Shared::OriginRelationship)
end

#not_a_cloneObject (private)



100
101
102
103
104
# File 'app/models/origin_relationship.rb', line 100

def not_a_clone
  if (old_object == new_object) || ((old_object_type == new_object_type) && (old_object_id == new_object_id))
    errors.add(:old_object, 'objects can not be cloned (related to each other)')
  end
end

#old_object_can_be_origin_of(klass) ⇒ Object (private)



89
90
91
92
# File 'app/models/origin_relationship.rb', line 89

def old_object_can_be_origin_of(klass)
  old_object.respond_to?(:valid_new_object_classes) &&
    old_object.valid_new_object_classes.include?(klass)
end

#old_object_respondsObject (private)



76
77
78
# File 'app/models/origin_relationship.rb', line 76

def old_object_responds
  errors.add(:old_object, "#{old_object.class.name} is not a legal part of an origin relationship") if !(old_object.class < Shared::OriginRelationship)
end

#pairing_is_allowedObject (private)



94
95
96
97
98
# File 'app/models/origin_relationship.rb', line 94

def pairing_is_allowed
  errors.add(:old_object, "#{old_object_type} is not a valid origin relationship old object of a #{new_object.class.name}") unless new_object_can_be_derived_from(old_object.class.name)

  errors.add(:new_object, "#{new_object_type} is not a valid origin relationship new object of a #{old_object.class.name}") unless old_object_can_be_origin_of(new_object.class.name)
end

#poll_old_and_new_objects_for_createObject (private)



106
107
108
109
110
111
112
113
114
115
116
# File 'app/models/origin_relationship.rb', line 106

def poll_old_and_new_objects_for_create
  if old_object.respond_to?(:allow_origin_relationship_create?) &&
     !old_object.allow_origin_relationship_create?(self)
    errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented create")
  end

  if new_object.respond_to?(:allow_origin_relationship_create?) &&
     !new_object.allow_origin_relationship_create?(self)
    errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented create")
  end
end

#poll_old_and_new_objects_for_destroyObject (private)



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/models/origin_relationship.rb', line 118

def poll_old_and_new_objects_for_destroy
  if old_object.respond_to?(:allow_origin_relationship_destroy?) &&
     !old_object.allow_origin_relationship_destroy?(self)
    errors.add(:base, "Old object #{old_object.class}:#{old_object.id} prevented destroy")
    old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
    new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

    throw(:abort)
  end

  if new_object.respond_to?(:allow_origin_relationship_destroy?) &&
     !new_object.allow_origin_relationship_destroy?(self)
    errors.add(:base, "New object #{new_object.class}:#{new_object.id} prevented destroy")
    old_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")
    new_object.errors.add(:base, "Origin relationship #{id} can't be destroyed")

    throw(:abort)
  end
end