Module: ChainLink

Extended by:
ActiveSupport::Concern
Defined in:
lib/chainlink.rb

Defined Under Namespace

Modules: ClassMethods Classes: DirectionError

Constant Summary collapse

MERGE_TARGET_KEY =
:merge_target_id
JOIN_TABLE_PREFIX =
:merge_target_

Instance Method Summary collapse

Instance Method Details

#merge!(source) ⇒ Object

Raises:



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chainlink.rb', line 67

def merge!(source)
  raise DirectionError, "source is not mergeable" unless source.mergeable?
  raise DirectionError, "target is not mergeable" unless mergeable?(:target)

  self.class.transaction do
    yield if block_given?
    source[MERGE_TARGET_KEY] ||= id
    source.save!
    save!
  end

  self
end

#merge_associations!(source, *associations) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'lib/chainlink.rb', line 81

def merge_associations!(source, *associations)
  Array(associations).each do |association_name|
    reflection = self.class.reflect_on_association(association_name)
    case reflection.macro
    when :has_many
      foreign_key = reflection.foreign_key
      reflection.klass.where(foreign_key => source.id).update_all(foreign_key => id)
    end
  end
end

#merge_targetObject



92
93
94
95
96
97
98
# File 'lib/chainlink.rb', line 92

def merge_target
  if !merged?
    self
  elsif target_record = self.class.find_by_id(merge_target_id)
    target_record.merge_target
  end
end

#merge_target_idObject



115
116
117
# File 'lib/chainlink.rb', line 115

def merge_target_id
  read_attribute(MERGE_TARGET_KEY)
end

#mergeable?(as = :source) ⇒ Boolean

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
# File 'lib/chainlink.rb', line 104

def mergeable?(as = :source)
  case as
  when :source
    !merged? && !merge_sources.exists?
  when :target
    !merged?
  else
    raise ArgumentError, "unknown merge role"
  end
end

#merged?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/chainlink.rb', line 100

def merged?
  merge_target_id.present?
end