Module: FmRest::Spyke::Model::Associations

Extended by:
ActiveSupport::Concern
Included in:
FmRest::Spyke::Model
Defined in:
lib/fmrest/spyke/model/associations.rb

Overview

This module adds portal support to Spyke models.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.has_portal(name, options = {}) ⇒ Object

Based on Spyke's has_many, but creates a special Portal association instead.

Examples:

class Person < FmRest::Spyke::Base
  has_portal :jobs, portal_key: "JobsTable", attribute_prefix: "Job"
end

Parameters:

  • :portal_key (Hash)

    a customizable set of options

  • :attribute_prefix (Hash)

    a customizable set of options



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/fmrest/spyke/model/associations.rb', line 41

def has_portal(name, options = {})
  # This is analogous to Spyke's create_association method, but using
  # our custom builder instead
  self.associations = associations.merge(name => PortalBuilder.new(self, name, Portal, options))

  # Store options for SpykeFormatter to use if needed
  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

Instance Method Details

#__new_portal_record_info=(data) ⇒ Object

Takes care of updating the new portal record's recordIds and modIds.

Called when saving a record with freshly added portal records, this method is not meant to be called manually.

Parameters:

  • data (Hash)

    The hash containing newPortalData from the DAPI response



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/fmrest/spyke/model/associations.rb', line 138

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? }

    # The DAPI provides only one recordId for the entire portal in the
    # newPortalRecordInfo object. This appears to be the recordId of
    # the last portal record created, so we assume all portal records
    # coming before it must have sequential recordIds up to the one we
    # do have.
    portal_new_records.reverse_each.with_index do |record, i|
      record.__record_id = d[:recordId].to_i - i

      # New records get a fresh modId
      record.__mod_id = 0
    end
  end
end

#association(name) ⇒ Object

Spyke override -- Keep a cache of loaded portals. Spyke's default behavior is to reload the association each time.



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/fmrest/spyke/model/associations.rb', line 59

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

#changed?Boolean

Override ActiveModel::Dirty's method to include awareness of @embedded_in_portal

Returns:

  • (Boolean)


127
128
129
# File 'lib/fmrest/spyke/model/associations.rb', line 127

def changed?
  super || embedded_in_portal?
end

#changes_appliedObject

Override ActiveModel::Dirty's method to include clearing of @embedded_in_portal and @marked_for_destruction



118
119
120
121
122
# File 'lib/fmrest/spyke/model/associations.rb', line 118

def changes_applied
  super
  @embedded_in_portal = nil
  @marked_for_destruction = nil
end

#embedded_in_portalObject

Signals that this record has been embedded in a portal so we can make sure to include it in the next update request



107
108
109
# File 'lib/fmrest/spyke/model/associations.rb', line 107

def embedded_in_portal
  @embedded_in_portal = true
end

#embedded_in_portal?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/fmrest/spyke/model/associations.rb', line 111

def embedded_in_portal?
  !!@embedded_in_portal
end

#mark_for_destructionObject Also known as: mark_for_deletion

Signals that this record has been marked for being deleted next time its parent record is saved (e.g. in a portal association)

This method is named after ActiveRecord's namesake



94
95
96
# File 'lib/fmrest/spyke/model/associations.rb', line 94

def mark_for_destruction
  @marked_for_destruction = true
end

#marked_for_destruction?Boolean Also known as: marked_for_deletion?

Returns:

  • (Boolean)


99
100
101
# File 'lib/fmrest/spyke/model/associations.rb', line 99

def marked_for_destruction?
  !!@marked_for_destruction
end

#portalsArray<FmRest::Spyke::Portal>

Returns A collection of portal relations for the record.

Returns:



81
82
83
84
85
86
87
# File 'lib/fmrest/spyke/model/associations.rb', line 81

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

#reload(*_) ⇒ Object

Spyke override -- Add portals awareness



74
75
76
# File 'lib/fmrest/spyke/model/associations.rb', line 74

def reload(*_)
  super.tap { @loaded_portals = nil }
end