module ModelTranscribers

Public Instance Methods

assign_attr(to:, by:) click to toggle source
# File lib/model_transcribers.rb, line 28
def assign_attr(to:, by:)
  attr_assignment[to] = ContentAdapter.new(to, by)
end
build_association() click to toggle source

Build the association between transcript and progenitor.

# File lib/model_transcribers.rb, line 40
def build_association
  has_one :transcript, class_name: transcript_model.name,
                       foreign_key: 'progenitor_id'
  progenitor_model = self
  transcript_model.class_eval do
    belongs_to :progenitor, class_name: progenitor_model.name,
                            foreign_key: 'progenitor_id'
  end
end
copy_attr(from:, to:, by: nil) click to toggle source
# File lib/model_transcribers.rb, line 24
def copy_attr(from:, to:, by: nil)
  attr_mapping[from] = ContentAdapter.new(to, by || from)
end
set_after_save_callback() click to toggle source

Set the “sync_to_xxxxx” method to after_save callback.

# File lib/model_transcribers.rb, line 51
def set_after_save_callback
  sync_method = "sync_to_#{transcript_model.name.underscore}".to_sym
  define_method(sync_method) do
    transcript.present? ? update_transcript : create_transcript
  end
  after_save(sync_method)
end
sync(transcript:) { || ... } click to toggle source
# File lib/model_transcribers.rb, line 12
def sync(transcript:)
  # Reset variables
  self.transcript_model = transcript
  self.attr_mapping = {}
  self.attr_assignment = {}

  yield

  build_association
  set_after_save_callback
end

Private Instance Methods

all_attrubites_to_be_updated() click to toggle source
# File lib/model_transcribers.rb, line 95
def all_attrubites_to_be_updated
  # To create a new transcript, we need fill up all attributes we
  # have defined.
  all_adapters = self.class.attr_mapping.values +
                 self.class.attr_assignment.values

  all_adapters.each_with_object({}) do |adapter, attrubites|
    content = adapter.content_from(self)
    attrubites[adapter.transcript] = content if content.present?
  end
end
create_transcript() click to toggle source
# File lib/model_transcribers.rb, line 74
def create_transcript
  create_transcript_in_raw_sql

  attrubites = all_attrubites_to_be_updated
  transcript.update_columns(attrubites)
end
create_transcript_in_raw_sql() click to toggle source
# File lib/model_transcribers.rb, line 81
def create_transcript_in_raw_sql
  table = self.class.transcript_model.table_name
  created_at = self.created_at.strftime('%F %T')
  updated_at = self.updated_at.strftime('%F %T')

  sql = "INSERT INTO #{table} (progenitor_id, created_at, updated_at) "\
        "VALUES (#{id}, '#{created_at}', '#{updated_at}')"
  ActiveRecord::Base.connection.execute(sql)

  # Bacuse we create the transcript by raw sql, so we need to force
  # database read otherwise the 'self.transcript' would be nil.
  reload_transcript
end
update_transcript() click to toggle source
# File lib/model_transcribers.rb, line 62
def update_transcript
  # Only update the changed attributes.
  attrs = saved_changes.keys.each_with_object({}) do |changed_attr, hash|
    adapter = self.class.attr_mapping[changed_attr.to_sym]
    hash[adapter.transcript] = adapter.content_from(self) unless adapter.nil?
  end

  return if attrs.blank?

  transcript.update_columns(attrs)
end