oddlyzen
6/22/2017 - 4:57 PM

Quill - ActiveAdmin BaseModel Sub-class

Quill - ActiveAdmin BaseModel Sub-class

class Quill::BaseModel
  include ActiveModel::Model
  attr_accessor :id, :access_token
 
  def self.special_attrs *attrs
    return @special_attrs unless attrs.any?
    @special_attrs = attrs
  end
 
  def self.inherited subclass
    subclass.special_attrs *@special_attrs
  end
 
  def self.attributes *attrs
    return @attributes if defined?(@attributes)
    @attributes = attrs
 
    attrs.dup.unshift(*@special_attrs).each do |attr|
      class_eval <<-CODE
        def #{attr}
          @data[:#{attr}]
        end
 
        def #{attr}= value
          @data[:#{attr}] = value
        end
      CODE
    end
  end
 
  def initialize *args
    @data = {}
    super
    load_model_attributes
  end
 
  def save(options={})
    perform_validations(options) ? persist : false
  end
 
  def persist
    data = @data.except(*self.class.special_attrs.dup)
    serialized_data = {}
 
    data.each do |key, value|
      serialized_data[key] = value.to_yaml
    end
 
    params = { data: serialized_data }
 
    self.class.special_attrs.each do |attr|
      params[attr] = send(attr)
    end
 
    params = filter_params(params) if respond_to?(:filter_params)
    object = persist_params params
    self.id = object.uid if id.blank?
    true
  end
 
  def load_model_attributes
    return unless key_present?
 
    object = find
    object.data = {} if object.data.nil?
    attrs = {}
 
    self.id = object.uid
 
    # load attributes defined on the superclass. These attributes
    # are designated by Quill.
    self.class.special_attrs.each do |attr|
      attrs[attr] = object.send(attr)
    end
 
    # load user defined attributes. This is arbitrary data that the app
    # has stored for this record.
    self.class.attributes.each do |attr|
      begin
        if object.data[attr].to_s[0..2] == '---'
          attrs[attr] = YAML.load(object.data[attr])
        else
          attrs[attr] = object.data[attr]
        end
      rescue Psych::SyntaxError
        attrs[attr] = object.data[attr]
      end
    end
 
    @data.reverse_merge!(attrs)
  end
 
  def save!
    save || raise
  end
 
  def inspect
    %Q|#<#{self.class.name} #{@data.map{|k,v| "#{k}=#{v.inspect}"}.join(' ')}>|
  end
 
protected
 
  def key_present?
     id.present?
  end
 
  def persist_params params
    if id.present?
      api.activity_sessions.update(id, params)
    else
      api.activity_sessions.create(params)
    end
  end
 
  def api
    @api ||= Quill::Client.new(access_token: access_token)
  end
 
  def perform_validations(options={})
    options[:validate] == false || valid?(options[:context])
  end
end