application_model.rb 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. # Copyright (C) 2013-2013 Zammad Foundation, http://zammad-foundation.org/
  2. require 'cache'
  3. require 'user_info'
  4. require 'sessions'
  5. class ApplicationModel < ActiveRecord::Base
  6. self.abstract_class = true
  7. before_create :cache_delete, :fill_up_user_create
  8. before_update :cache_delete_before, :fill_up_user_update
  9. before_destroy :cache_delete_before
  10. after_create :cache_delete
  11. after_update :cache_delete
  12. after_destroy :cache_delete
  13. @@import_class_list = ['Ticket', 'Ticket::Article', 'History', 'Ticket::State', 'Ticket::Priority', 'Group', 'User' ]
  14. # for import of other objects, remove 'id'
  15. def self.attributes_protected_by_default
  16. if Setting.get('import_mode') && @@import_class_list.include?( self.name.to_s )
  17. ['type']
  18. else
  19. ['id','type']
  20. end
  21. end
  22. =begin
  23. remove all not used model attributes of params
  24. result = Model.param_cleanup(params)
  25. returns
  26. result = params # params with valid attributes of model
  27. =end
  28. def self.param_cleanup(params)
  29. # only use object attributes
  30. data = {}
  31. self.new.attributes.each {|item|
  32. if params.has_key?(item[0])
  33. # puts 'use ' + item[0].to_s + '-' + params[item[0]].to_s
  34. data[item[0].to_sym] = params[item[0]]
  35. end
  36. }
  37. # we do want to set this via database
  38. self.param_validation(data)
  39. end
  40. =begin
  41. remove all not used params of object (per default :updated_at, :created_at, :updated_by_id and :created_by_id)
  42. result = Model.param_validation(params)
  43. returns
  44. result = params # params without listed attributes
  45. =end
  46. def self.param_validation(data)
  47. # we do want to set this via database
  48. data.delete( :updated_at )
  49. data.delete( :created_at )
  50. data.delete( :updated_by_id )
  51. data.delete( :created_by_id )
  52. data
  53. end
  54. =begin
  55. set created_by_id & updated_by_id if not given based on UserInfo (current session)
  56. Used as before_create callback, no own use needed
  57. result = Model.fill_up_user_create(params)
  58. returns
  59. result = params # params with updated_by_id & created_by_id if not given based on UserInfo (current session)
  60. =end
  61. def fill_up_user_create
  62. if self.class.column_names.include? 'updated_by_id'
  63. if UserInfo.current_user_id
  64. if self.updated_by_id && self.updated_by_id != UserInfo.current_user_id
  65. puts "NOTICE create - self.updated_by_id is different: #{self.updated_by_id.to_s}/#{UserInfo.current_user_id.to_s}"
  66. end
  67. self.updated_by_id = UserInfo.current_user_id
  68. end
  69. end
  70. if self.class.column_names.include? 'created_by_id'
  71. if UserInfo.current_user_id
  72. if self.created_by_id && self.created_by_id != UserInfo.current_user_id
  73. puts "NOTICE create - self.created_by_id is different: #{self.created_by_id.to_s}/#{UserInfo.current_user_id.to_s}"
  74. end
  75. self.created_by_id = UserInfo.current_user_id
  76. end
  77. end
  78. end
  79. =begin
  80. set updated_by_id if not given based on UserInfo (current session)
  81. Used as before_update callback, no own use needed
  82. result = Model.fill_up_user_update(params)
  83. returns
  84. result = params # params with updated_by_id & created_by_id if not given based on UserInfo (current session)
  85. =end
  86. def fill_up_user_update
  87. return if !self.class.column_names.include? 'updated_by_id'
  88. if UserInfo.current_user_id
  89. self.updated_by_id = UserInfo.current_user_id
  90. end
  91. end
  92. def cache_update(o)
  93. # puts 'u ' + self.class.to_s
  94. if self.respond_to?('cache_delete') then self.cache_delete end
  95. # puts 'g ' + group.class.to_s
  96. if o.respond_to?('cache_delete') then o.cache_delete end
  97. end
  98. def cache_delete_before
  99. old_object = self.class.where( :id => self.id ).first
  100. if old_object
  101. old_object.cache_delete
  102. end
  103. self.cache_delete
  104. end
  105. def cache_delete
  106. key = self.class.to_s + '::' + self.id.to_s
  107. Cache.delete( key.to_s )
  108. key = self.class.to_s + ':f:' + self.id.to_s
  109. Cache.delete( key.to_s )
  110. if self[:name]
  111. key = self.class.to_s + '::' + self.name.to_s
  112. Cache.delete( key.to_s )
  113. key = self.class.to_s + ':f:' + self.name.to_s
  114. Cache.delete( key.to_s )
  115. end
  116. if self[:login]
  117. key = self.class.to_s + '::' + self.login.to_s
  118. Cache.delete( key.to_s )
  119. key = self.class.to_s + ':f:' + self.login.to_s
  120. Cache.delete( key.to_s )
  121. end
  122. end
  123. def self.cache_set(data_id, data, full = false)
  124. if !full
  125. key = self.to_s + '::' + data_id.to_s
  126. else
  127. key = self.to_s + ':f:' + data_id.to_s
  128. end
  129. Cache.write( key.to_s, data )
  130. end
  131. def self.cache_get(data_id, full = false)
  132. if !full
  133. key = self.to_s + '::' + data_id.to_s
  134. else
  135. key = self.to_s + ':f:' + data_id.to_s
  136. end
  137. Cache.get( key.to_s )
  138. end
  139. =begin
  140. lookup model from cache (if exists) or retrieve it from db, id, name or login possible
  141. result = Model.lookup( :id => 123 )
  142. result = Model.lookup( :name => 'some name' )
  143. result = Model.lookup( :login => 'some login' )
  144. returns
  145. result = model # with all attributes
  146. =end
  147. def self.lookup(data)
  148. if data[:id]
  149. # puts "GET- + #{self.to_s}.#{data[:id].to_s}"
  150. cache = self.cache_get( data[:id] )
  151. return cache if cache
  152. # puts "Fillup- + #{self.to_s}.#{data[:id].to_s}"
  153. record = self.where( :id => data[:id] ).first
  154. self.cache_set( data[:id], record )
  155. return record
  156. elsif data[:name]
  157. cache = self.cache_get( data[:name] )
  158. return cache if cache
  159. records = self.where( :name => data[:name] )
  160. records.each {|record|
  161. if record.name == data[:name]
  162. self.cache_set( data[:name], record )
  163. return record
  164. end
  165. }
  166. return
  167. elsif data[:login]
  168. cache = self.cache_get( data[:login] )
  169. return cache if cache
  170. records = self.where( :login => data[:login] )
  171. records.each {|record|
  172. if record.login == data[:login]
  173. self.cache_set( data[:login], record )
  174. return record
  175. end
  176. }
  177. return
  178. else
  179. raise "Need name, id or login for lookup()"
  180. end
  181. end
  182. =begin
  183. create model if not exists (check exists based on id, name, login or locale)
  184. result = Model.create_if_not_exists( attributes )
  185. returns
  186. result = model # with all attributes
  187. =end
  188. def self.create_if_not_exists(data)
  189. if data[:id]
  190. record = self.where( :id => data[:id] ).first
  191. return record if record
  192. elsif data[:name]
  193. records = self.where( :name => data[:name] )
  194. records.each {|record|
  195. return record if record.name == data[:name]
  196. }
  197. elsif data[:login]
  198. records = self.where( :login => data[:login] )
  199. records.each {|record|
  200. return record if record.login == data[:login]
  201. }
  202. elsif data[:locale] && data[:source]
  203. records = self.where( :locale => data[:locale], :source => data[:source] )
  204. records.each {|record|
  205. return record if record.source == data[:source]
  206. }
  207. end
  208. self.create(data)
  209. end
  210. =begin
  211. create or update model (check exists based on name, login or locale)
  212. result = Model.create_or_update( attributes )
  213. returns
  214. result = model # with all attributes
  215. =end
  216. def self.create_or_update(data)
  217. if data[:name]
  218. records = self.where( :name => data[:name] )
  219. records.each {|record|
  220. if record.name == data[:name]
  221. record.update_attributes( data )
  222. return record
  223. end
  224. }
  225. record = self.new( data )
  226. record.save
  227. return record
  228. elsif data[:login]
  229. records = self.where( :login => data[:login] )
  230. records.each {|record|
  231. if record.login.downcase == data[:login].downcase
  232. record.update_attributes( data )
  233. return record
  234. end
  235. }
  236. record = self.new( data )
  237. record.save
  238. return record
  239. elsif data[:locale]
  240. records = self.where( :locale => data[:locale] )
  241. records.each {|record|
  242. if record.locale.downcase == data[:locale].downcase
  243. record.update_attributes( data )
  244. return record
  245. end
  246. }
  247. record = self.new( data )
  248. record.save
  249. return record
  250. else
  251. raise "Need name, login or locale for create_or_update()"
  252. end
  253. end
  254. =begin
  255. notify_clients_after_create after model got created
  256. used as callback in model file
  257. class OwnModel < ApplicationModel
  258. after_create :notify_clients_after_create
  259. after_update :notify_clients_after_update
  260. after_destroy :notify_clients_after_destroy
  261. [...]
  262. =end
  263. def notify_clients_after_create
  264. # return if we run import mode
  265. return if Setting.get('import_mode')
  266. class_name = self.class.name
  267. class_name.gsub!(/::/, '')
  268. Sessions.broadcast(
  269. :event => class_name + ':created',
  270. :data => { :id => self.id, :updated_at => self.updated_at }
  271. )
  272. end
  273. =begin
  274. notify_clients_after_update after model got updated
  275. used as callback in model file
  276. class OwnModel < ApplicationModel
  277. after_create :notify_clients_after_create
  278. after_update :notify_clients_after_update
  279. after_destroy :notify_clients_after_destroy
  280. [...]
  281. =end
  282. def notify_clients_after_update
  283. # return if we run import mode
  284. return if Setting.get('import_mode')
  285. puts "#{self.class.name.downcase} UPDATED " + self.updated_at.to_s
  286. class_name = self.class.name
  287. class_name.gsub!(/::/, '')
  288. Sessions.broadcast(
  289. :event => class_name + ':updated',
  290. :data => { :id => self.id, :updated_at => self.updated_at }
  291. )
  292. end
  293. =begin
  294. notify_clients_after_destroy after model got destroyed
  295. used as callback in model file
  296. class OwnModel < ApplicationModel
  297. after_create :notify_clients_after_create
  298. after_update :notify_clients_after_update
  299. after_destroy :notify_clients_after_destroy
  300. [...]
  301. =end
  302. def notify_clients_after_destroy
  303. # return if we run import mode
  304. return if Setting.get('import_mode')
  305. puts "#{self.class.name.downcase} DESTOY " + self.updated_at.to_s
  306. class_name = self.class.name
  307. class_name.gsub!(/::/, '')
  308. Sessions.broadcast(
  309. :event => class_name + ':destroy',
  310. :data => { :id => self.id, :updated_at => self.updated_at }
  311. )
  312. end
  313. end