Guest User

Untitled

a guest
Jan 21st, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.25 KB | None | 0 0
  1. module Mongoid
  2. module Undo
  3. extend ActiveSupport::Concern
  4.  
  5. included do
  6. include Mongoid::Document
  7.  
  8. field :version, type: Integer, default: 0
  9. before_save :prepare_versioning
  10. after_save :create_version
  11. before_destroy :version_destroy
  12. end
  13.  
  14. def versions; ::Version.where(obj_id: id) end
  15. def versions_gt(version = self.version); versions.where(:version.gt => version) end
  16. def version_at(version = self.version); versions.where(version: version).first end
  17. def current_version; version_at end
  18. def previous_version; version_at version - 1 end
  19.  
  20. def versioned?; version > 0 end
  21. def has?(ver)
  22. ver.obj_id == id && ver.obj_class == self.class.to_s
  23. end
  24. def matches?(ver)
  25. has?(ver) &&
  26. ver.obj_attributes == attributes &&
  27. ver.version == version
  28. end
  29.  
  30. def undo!; rollback_to!(version - 1) end
  31.  
  32. def rollback_to!(version)
  33. unless persisted?; return false end
  34. if version == 0
  35. versions.destroy
  36. without_versioning :destroy
  37. attributes
  38. else
  39. ver = version_at(version)
  40. unless ver; return false end
  41.  
  42. ver.rollback_to(self)
  43. end
  44. end
  45.  
  46. def without_versioning(method = nil)
  47. @without_versioning = true
  48. method ? method.to_proc.call(self) : yield
  49. ensure
  50. @without_versioning = false
  51. end
  52.  
  53. private
  54. def match_persisted?
  55. current_version && attributes == current_version.obj_attributes
  56. end
  57.  
  58. def prepare_versioning
  59. if !@without_versioning
  60. if version == 0 && persisted?
  61. self.version += 1
  62. old_self = self.class.find(id)
  63. old_self.version += 1
  64. old_self.send(:create_version)
  65. end
  66. if !match_persisted?; self.version += 1 end
  67. end
  68. end
  69.  
  70. def create_version(destroy = false)
  71. if !@without_versioning && (destroy || !match_persisted?)
  72. ver = ::Version.new(obj_id: id, obj_class: self.class.to_s, version: version)
  73. unless destroy; ver.attributes = ver.attributes.merge({:obj_attributes => attributes}) end
  74. ver.save!
  75. end
  76. end
  77.  
  78. def version_destroy
  79. if !@without_versioning
  80. self.version += 1
  81. without_versioning(:save)
  82. create_version(true)
  83. end
  84. end
  85. end
  86. end
Add Comment
Please, Sign In to add comment