Class: Volt::Persistors::ModelStore

Inherits:
Store show all
Includes:
StoreState
Defined in:
lib/volt/models/persistors/model_store.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Store

#clear_identity_map, #inspect, #read_new_model, #saved?

Methods inherited from Base

#added, #async?, #clear, #event_removed, #removed, #root_model

Constructor Details

#initialize(model, tasks) ⇒ ModelStore

Returns a new instance of ModelStore.



12
13
14
15
16
# File 'lib/volt/models/persistors/model_store.rb', line 12

def initialize(model, tasks)
  super

  @in_identity_map = false
end

Instance Attribute Details

#in_identity_mapObject

Returns the value of attribute in_identity_map.



10
11
12
# File 'lib/volt/models/persistors/model_store.rb', line 10

def in_identity_map
  @in_identity_map
end

#modelObject (readonly)

Returns the value of attribute model.



9
10
11
# File 'lib/volt/models/persistors/model_store.rb', line 9

def model
  @model
end

Class Method Details

.changed(model_id, data) ⇒ Object

Update the models based on the id/identity map. Usually these requests will come from the backend.



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/volt/models/persistors/model_store.rb', line 133

def self.changed(model_id, data)
  Model.no_save do
    model = @@identity_map.lookup(model_id)

    if model
      data.each_pair do |key, value|
        model.set(key, value)# if key != :id
      end
    end
  end
end

Instance Method Details

#[](val) ⇒ Object



145
146
147
# File 'lib/volt/models/persistors/model_store.rb', line 145

def [](val)
  fail 'Models do not support hash style lookup.  Hashes inserted into other models are converted to models, see https://github.com/voltrb/volt#automatic-model-conversion'
end

#add_to_identity_mapObject



33
34
35
36
37
38
39
# File 'lib/volt/models/persistors/model_store.rb', line 33

def add_to_identity_map
  unless @in_identity_map
    @@identity_map.add(@model.id, @model)

    @in_identity_map = true
  end
end

#auto_generate_idObject



24
25
26
# File 'lib/volt/models/persistors/model_store.rb', line 24

def auto_generate_id
  true
end

#changed(attribute_name = nil) ⇒ Object

Called when the model changes



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/volt/models/persistors/model_store.rb', line 50

def changed(attribute_name = nil)
  path = @model.path

  promise = Promise.new

  ensure_setup

  path_size = path.size
  if save_changes? && path_size > 0 && !@model.nil?
    if path_size > 3 && (parent = @model.parent)
      # If we have a collection, go up one more.
      parent = parent.parent unless parent.is_a?(Volt::Model)
      @model.attributes[:"#{path[-4].singularize}_id"] = parent.id
    end

    if !collection
      puts 'Attempting to save model directly on store.'
      fail 'Attempting to save model directly on store.'
    else
      if RUBY_PLATFORM == 'opal'
        @save_promises ||= []
        @save_promises << promise

        queue_client_save
      else
        errors = save_to_db!(self_attributes)
        if errors.size == 0
          promise.resolve(nil)
        else
          promise.reject(errors)
        end
      end
    end
  end

  promise
end

#ensure_setupObject

Called the first time a value is assigned into this model



29
30
31
# File 'lib/volt/models/persistors/model_store.rb', line 29

def ensure_setup
  add_to_identity_map
end

#event_added(event, first, first_for_event) ⇒ Object



127
128
129
# File 'lib/volt/models/persistors/model_store.rb', line 127

def event_added(event, first, first_for_event)
  ensure_setup if first_for_event && event == :changed
end

#loaded(initial_state = nil) ⇒ Object



18
19
20
21
22
# File 'lib/volt/models/persistors/model_store.rb', line 18

def loaded(initial_state = nil)
  initial_state = :loaded if model.path == []

  model.change_state_to(:loaded_state, initial_state)
end

#queue_client_saveObject



88
89
90
91
92
93
94
# File 'lib/volt/models/persistors/model_store.rb', line 88

def queue_client_save
  `
  if (!self.saveTimer) {
    self.saveTimer = setImmediate(self.$run_save.bind(self));
  }
  `
end

#run_saveObject

Run save is called on the client side after a queued setImmediate. It does the saving on the front-end. Adding a setImmediate allows multiple changes to be batched together.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/volt/models/persistors/model_store.rb', line 99

def run_save
  # Clear the save timer
  `
  clearImmediate(self.saveTimer);
  delete self.saveTimer;
  `

  @model.change_state_to(:saved_state, :saving)

  StoreTasks.save(collection, @model.path, self_attributes).then do
    save_promises = @save_promises
    @save_promises = nil
    save_promises.each { |promise|  promise.resolve(nil) }

    @model.change_state_to(:saved_state, :saved)
  end.fail do |errors|
    save_promises = @save_promises
    @save_promises = nil

    # Rewrap in Volt::Errors
    errors = Volt::Errors.new(errors)
    save_promises.each { |promise| promise.reject(errors) }

    # Mark that we failed to save
    @model.change_state_to(:saved_state, :save_failed)
  end
end

#save_changes?Boolean

Returns:



41
42
43
44
45
46
47
# File 'lib/volt/models/persistors/model_store.rb', line 41

def save_changes?
  if RUBY_PLATFORM == 'opal'
    !(defined?($loading_models) && $loading_models) && @tasks
  else
    true
  end
end