require "fmrest/spyke/portal_builder"
require "fmrest/spyke/portal"
module FmRest
module Spyke
module Model
module Associations
extend ::ActiveSupport::Concern
included do
class_attribute :portal_options, instance_accessor: false, instance_predicate: false,
default: {}.freeze
class << self; private :portal_options=; end
set_callback :save, :after, :remove_marked_for_destruction
end
class_methods do
def has_portal(name, options = {})
self.associations = associations.merge(name => PortalBuilder.new(self, name, Portal, options))
portal_key = options[:portal_key] || name
self.portal_options = portal_options.merge(portal_key.to_s => options.dup.merge(name: name.to_s).freeze).freeze
define_method "#{name.to_s.singularize}_ids" do
association(name).map(&:id)
end
end
end
def association(name)
@loaded_portals ||= {}
if @loaded_portals.has_key?(name.to_sym)
return @loaded_portals[name.to_sym]
end
super.tap do |assoc|
next unless assoc.kind_of?(FmRest::Spyke::Portal)
@loaded_portals[name.to_sym] = assoc
end
end
def reload(*_)
super.tap { @loaded_portals = nil }
end
def portals
self.class.associations.each_with_object([]) do |(key, _), portals|
candidate = association(key)
next unless candidate.kind_of?(FmRest::Spyke::Portal)
portals << candidate
end
end
def mark_for_destruction
@marked_for_destruction = true
end
alias_method :mark_for_deletion, :mark_for_destruction
def marked_for_destruction?
!!@marked_for_destruction
end
alias_method :marked_for_deletion?, :marked_for_destruction?
def embedded_in_portal
@embedded_in_portal = true
end
def embedded_in_portal?
!!@embedded_in_portal
end
def changes_applied
super
@embedded_in_portal = nil
@marked_for_destruction = nil
end
def changed?
super || embedded_in_portal?
end
def __new_portal_record_info=(data)
data.each do |d|
table_name = d[:tableName]
portal_new_records =
portals.detect { |p| p.portal_key == table_name }.select { |r| !r.persisted? }
portal_new_records.reverse_each.with_index do |record, i|
record.__record_id = d[:recordId].to_i - i
record.__mod_id = 0
end
end
end
private
def remove_marked_for_destruction
portals.each(&:_remove_marked_for_destruction)
end
end
end
end
end