Class: Offroad::ReceivedRecordState
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Offroad::ReceivedRecordState
- Defined in:
- lib/app/models/offroad/received_record_state.rb
Constant Summary
Constants included from ModelExtensions
ModelExtensions::OFFROAD_GROUP_MODES, ModelExtensions::OFFROAD_VALID_MODES
Class Method Summary collapse
Instance Method Summary collapse
Methods included from ModelExtensions
#acts_as_offroadable, #acts_as_offroadable?, #offroad_global_data?, #offroad_group_base?, #offroad_group_data?, #offroad_model_state, #safe_to_load_from_cargo_stream?
Class Method Details
.redirect_to_local_ids(records, column, model, group) ⇒ Object
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/app/models/offroad/received_record_state.rb', line 60 def self.redirect_to_local_ids(records, column, model, group) column = column.to_sym source = self.for_model_and_group_if_apropos(model, group) already_allocated = source.all(:conditions => { :remote_record_id => records.map{|r| r[column]} }).index_by(&:remote_record_id) remaining = {} # Maps newly discovered remote id to list of records in batch that reference that id records.each do |r| remote_id = r[column] next unless remote_id && remote_id > 0 # TODO Check for illegal references here (i.e. group model referencing global model) if already_allocated.has_key?(remote_id) r[column] = already_allocated[remote_id].local_record_id else # Target doesn't exist yet, we'll figure out what its local id will be later if remaining.has_key?(remote_id) remaining[remote_id] << r else remaining[remote_id] = [r] end end end return unless remaining.size > 0 # Reserve access to a block of local ids if model.connection.adapter_name.downcase.include?("postgres") nextval_cmd = model.connection.select_value("SELECT column_default FROM information_schema.columns WHERE table_name = '#{model.table_name}' AND column_name = '#{model.primary_key}'") local_ids = model.connection.select_values("SELECT #{nextval_cmd} FROM generate_series(1,#{remaining.size})").map(&:to_i) else # Reserve access to a block of local ids by creating temporary records to advance the autoincrement counter # TODO I'm pretty sure this is safe because it'll always be used in a transaction, but I should check model.import([model.primary_key.to_sym], [[nil]]*remaining.size, :validate => false, :timestamps => false) last_id = model.last(:select => model.primary_key, :order => model.primary_key).id local_ids = ((last_id+1-remaining.size)..last_id).to_a model.delete(local_ids) end # Create the corresponding RRSes model_state_id = model.offroad_model_state.id group_state = model.offroad_group_data? && group ? group.group_state : nil group_state_id = group_state ? group_state.id : 0 self.import( [:model_state_id, :group_state_id, :local_record_id, :remote_record_id], local_ids.zip(remaining.keys).map{|here, there| [model_state_id, group_state_id, here, there]}, :validate => false, :timestamps => false ) # Finally do the redirection to the new ids remaining.each_key.each_with_index do |remote_id, i| remaining[remote_id].each do |r| r[column] = local_ids[i] end end end |
Instance Method Details
#app_record ⇒ Object
56 57 58 |
# File 'lib/app/models/offroad/received_record_state.rb', line 56 def app_record model_state.app_model.find(local_record_id) end |
#validate ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/app/models/offroad/received_record_state.rb', line 11 def validate unless model_state errors.add_to_base "Cannot find associated model state" return end model = model_state.app_model if Offroad::app_offline? if model.offroad_group_data? errors.add_to_base "Cannot allow received record state for group data in offline app" end elsif Offroad::app_online? if model.offroad_global_data? errors.add_to_base "Cannot allow received record state for global records in online app" elsif group_state.nil? errors.add_to_base "Cannot allow received record state for online group records in online app" end end if model.offroad_global_data? && group_state errors.add_to_base "Cannot allow received record state for global records to also be assoc with a group" end begin app_record rescue ActiveRecord::RecordNotFound errors.add_to_base "Cannot find associated app record" end end |