lib/active_metadata/base.rb in active_metadata-0.2.4 vs lib/active_metadata/base.rb in active_metadata-0.3.0
- old
+ new
@@ -5,12 +5,12 @@
## Define ModelMethods
module Base
require 'paperclip'
- require "active_metadata/persistence/persistence"
- require "active_metadata/helpers"
+ require 'active_metadata/persistence/persistence'
+ require 'active_metadata/helpers'
def self.included(klass)
klass.class_eval do
extend Config
end
@@ -35,15 +35,10 @@
module InstanceMethods
include ActiveMetadata::Helpers
- def attributes=(attributes)
- attributes.delete(:active_metadata_timestamp) unless attributes[:active_metadata_timestamp].nil?
- super
- end
-
def self.included(klass)
[:notes, :attachments, :history].each do |item|
klass.send(:define_method, "#{item.to_s}_cache_key".to_sym) do |field|
"#{Rails.env}/active_metadata/#{item.to_s}/#{self.class}/#{metadata_id}/#{field}/"
end
@@ -52,12 +47,15 @@
def metadata_id
metadata_root.id
end
- def active_metadata_timestamp
- metadata_root.active_metadata_timestamp || nil
+ # Normalize the active_metadata_timestamp into a float to be comparable with the history
+ def am_timestamp
+ ts = metadata_root.active_metadata_timestamp
+ return nil if ts.nil?
+ ts = ts.to_f
end
def current_user_id
if User.respond_to?(:current) && !User.current.nil?
User.current.id
@@ -76,11 +74,10 @@
receiver
end
# Resolve concurrency using the provided timestamps and the active_metadata histories.
# Conflicts are stored into @conflicts instance variable
- #
# Timestamp used for versioning can be passed both as :
# ====
# * @object.active_metadata_timestamp = ....
# * @object.update_attributes :active_metadata_timestamp => ...
#
@@ -93,37 +90,35 @@
#
# * @conflicts[:fatals] contains any conflict that "do not apply cleanly" or where the passed value does not match the last history value and was modified
# by the user that is submittig the data
#
def manage_concurrency
- return if active_metadata_timestamp.nil? #if no timestamp no way to check concurrency so just skip
+ timestamp = self.am_timestamp
+ return if timestamp.nil? #if no timestamp no way to check concurrency so just skip
self.conflicts = { :warnings => [], :fatals => [] }
# scan params
self.attributes.each do |key, val|
# ensure the query order
histories = history_for key.to_sym, "created_at DESC"
+ next if histories.count == 0 #if history does not exists yet cannot be a conflict
+
latest_history = histories.first
- timestamp = self.active_metadata_timestamp
- # if form timestamp is subsequent the history last change go on
- # if history does not exists yet go on
- next if latest_history.nil? || timestamp > latest_history.created_at
-
#if the timestamp is previous of the last history change
- if timestamp < latest_history.created_at
+ if timestamp < latest_history.created_at.to_f
begin
self[key.to_sym] = self.changes[key][0]
rescue
end # there is a conflict so ensure the actual value if any change exists
# We have a conflict.
# Check if the actual submission has been modified
histories.each do |h|
# Looking for the value that was loaded by the user. First history with a ts that is younger than the form ts
- next if timestamp > h.created_at
+ next if timestamp > h.created_at.to_f
# History stores values as strings so any boolean is stored as "0" or "1"
# We need to translate the params passed for a safer comparison.
if self.column_for_attribute(key).type == :boolean
b_val = to_bool(h.value)