Module: ActiveMetadata::Base::InstanceMethods

Includes:
Helpers
Defined in:
lib/active_metadata/base.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#to_bool

Class Method Details

.included(klass) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/active_metadata/base.rb', line 54

def self.included(klass)

  [:notes, :attachments, :history].each do |item|
    klass.send(:define_method, "#{item.to_s}_cache_key".to_sym) do |field|
      "#{CONFIG['cache_prefix'] + Rails.env}:active_metadata/#{item.to_s}/#{self.class}/#{}/#{field}/"
    end
  end

  [:fatals, :warnings].each do |conf|
    klass.send(:define_method, "has_#{conf.to_s}_conflicts?".to_sym) do
      return false if self.conflicts.nil? || self.conflicts[conf.to_sym].nil? || self.conflicts[conf.to_sym].empty?
      true
    end
  end

end

Instance Method Details

#am_timestampObject

Normalize the active_metadata_timestamp into a float to be comparable with the history



84
85
86
87
88
# File 'lib/active_metadata/base.rb', line 84

def am_timestamp
  ts = .
  return nil if ts.nil?
  ts = ts.to_f
end

#current_user_idObject



90
91
92
93
94
95
96
# File 'lib/active_metadata/base.rb', line 90

def current_user_id
  if User.respond_to?(:current) && !User.current.nil?
    User.current.id
  else
    nil
  end
end

#manage_concurrencyObject

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 => …

Check is skipped if no timestamp exists. A check is made also for parents defined via acts_as_metadata method

Conflicts

  • @conflicts contains any conflict that “apply cleanly” or where the submit value has not been modified by the user that is saving

the data.
  • @conflicts 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



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/active_metadata/base.rb', line 121

def manage_concurrency
  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"

    # if history does not exists yet cannot be a conflict  OR
    # if value has no change respect to the latest db saved we have no conflict
    next if histories.count == 0 || self.changes[key].nil?

    latest_history = histories.first

    #if the timestamp is previous of the last history change
    if timestamp < latest_history.created_at.to_f

      # We have a conflict.
      # Check if the actual submission has been modified
      histories.each_with_index do |h,i|
        # Looking for the value that was loaded by the user. First history with a ts that is younger than the form ts
        next if h.created_at.to_f > timestamp

        # 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)
        end

        # conflict ensure the actual value is not modified
        self[key.to_sym] = self.changes[key][0]

        if [h.value, b_val].include? val
          self.conflicts[:warnings] << {key.to_sym => latest_history}
        else
          self.conflicts[:fatals] << {key.to_sym => latest_history}
        end

        break #done for this field
      end

    end

  end

end

#metadata_class(force = false) ⇒ Object

same as #metadata_id



79
80
81
# File 'lib/active_metadata/base.rb', line 79

def  force=false
  force ? .class.to_s : .class.to_s
end

#metadata_id(force = false) ⇒ Object

if force is set to true go directly to the private find method options integrity will not be checked and ancestor will be looked also if option persists_ancestor is false usefull to get the ancestor instance also if is not persisted



74
75
76
# File 'lib/active_metadata/base.rb', line 74

def  force=false
  force ? .id : .id
end

#metadata_rootObject



98
99
100
101
102
# File 'lib/active_metadata/base.rb', line 98

def 
  options = self.class.instance_variable_get("@active_metadata_options")
  return self unless (options[:persists_ancestor] && options[:ancestors].size > 0 )
  
end