application_model.rb 10 KB

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