erp_tech_svcs 3.0.12 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. data/app/controllers/erp_tech_svcs/session_controller.rb +1 -1
  2. data/app/models/attribute_type.rb +2 -0
  3. data/app/models/attribute_value.rb +2 -0
  4. data/app/models/audit_log.rb +4 -1
  5. data/app/models/audit_log_item.rb +2 -0
  6. data/app/models/audit_log_item_type.rb +2 -0
  7. data/app/models/audit_log_type.rb +2 -0
  8. data/app/models/capability.rb +2 -1
  9. data/app/models/capability_type.rb +2 -0
  10. data/app/models/extensions/category.rb +3 -0
  11. data/app/models/extensions/compass_ae_instance.rb +3 -0
  12. data/app/models/file_asset.rb +3 -1
  13. data/app/models/group.rb +5 -18
  14. data/app/models/scope_type.rb +1 -0
  15. data/app/models/security_role.rb +2 -0
  16. data/app/models/user.rb +29 -42
  17. data/app/views/user_mailer/activation_needed_email.html.erb +1 -1
  18. data/app/views/user_mailer/reset_password_email.html.erb +1 -1
  19. data/config/initializers/erp_tech_svcs.rb +2 -0
  20. data/db/data_migrations/20121130212146_note_capabilities.rb +2 -2
  21. data/db/migrate/20080805000010_base_tech_services.rb +3 -3
  22. data/lib/erp_tech_svcs/config.rb +4 -0
  23. data/lib/erp_tech_svcs/extensions/active_record/acts_as_versioned.rb +105 -106
  24. data/lib/erp_tech_svcs/extensions/active_record/has_capability_accessors.rb +4 -10
  25. data/lib/erp_tech_svcs/extensions/active_record/has_security_roles.rb +2 -0
  26. data/lib/erp_tech_svcs/extensions/active_record/protected_with_capabilities.rb +28 -53
  27. data/lib/erp_tech_svcs/extensions/railties/action_view/base.rb +8 -0
  28. data/lib/erp_tech_svcs/extensions/railties/action_view/helpers/include_helper.rb +28 -0
  29. data/lib/erp_tech_svcs/extensions.rb +3 -0
  30. data/lib/erp_tech_svcs/file_support/railties/s3_resolver.rb +1 -1
  31. data/lib/erp_tech_svcs/sms_wrapper/clickatell.rb +3 -3
  32. data/lib/erp_tech_svcs/utils/compass_access_negotiator.rb +4 -6
  33. data/lib/erp_tech_svcs/version.rb +2 -2
  34. data/lib/erp_tech_svcs.rb +2 -1
  35. data/spec/dummy/config/application.rb +6 -0
  36. data/spec/dummy/config/environments/spec.rb +3 -0
  37. data/spec/dummy/config/s3.yml +23 -0
  38. data/spec/dummy/db/data_migrations/20120109173616_create_download_capability_type.erp_tech_svcs.rb +14 -0
  39. data/spec/dummy/db/migrate/{20130105133955_base_erp_services.erp_base_erp_svcs.rb → 20130107214445_base_erp_services.erp_base_erp_svcs.rb} +0 -0
  40. data/spec/dummy/db/migrate/{20130105133956_base_tech_services.erp_tech_svcs.rb → 20130107214446_base_tech_services.erp_tech_svcs.rb} +0 -0
  41. data/spec/dummy/db/migrate/{20130105133957_create_has_attribute_tables.erp_tech_svcs.rb → 20130107214447_create_has_attribute_tables.erp_tech_svcs.rb} +0 -0
  42. data/spec/dummy/db/migrate/{20130105133958_create_groups.erp_tech_svcs.rb → 20130107214448_create_groups.erp_tech_svcs.rb} +0 -0
  43. data/spec/dummy/db/migrate/{20130105133959_upgrade_security.erp_tech_svcs.rb → 20130107214449_upgrade_security.erp_tech_svcs.rb} +0 -0
  44. data/spec/dummy/db/migrate/{20130105133960_upgrade_security2.erp_tech_svcs.rb → 20130107214450_upgrade_security2.erp_tech_svcs.rb} +0 -0
  45. data/spec/dummy/db/schema.rb +1 -1
  46. data/spec/dummy/db/spec.sqlite3 +0 -0
  47. data/spec/dummy/log/spec.log +15314 -121571
  48. data/spec/dummy/move_test_tmp/file_asset_spec_text.txt +1 -0
  49. data/spec/lib/erp_tech_svcs/extensions/active_record/has_roles_spec.rb +6 -6
  50. data/spec/lib/file_support/s3_manager_spec.rb +1 -0
  51. data/spec/models/audit_log_spec.rb +1 -1
  52. data/spec/models/file_asset_spec.rb +14 -5
  53. data/spec/models/group_spec.rb +41 -0
  54. data/spec/models/security_role_spec.rb +26 -0
  55. data/spec/models/user_spec.rb +12 -2
  56. data/spec/spec_helper.rb +12 -7
  57. metadata +65 -48
  58. data/db/data_migrations/upgrade/20120727152144_set_image_dimensions_on_file_assets.rb +0 -13
  59. data/db/migrate/upgrade/20111109161549_add_capabilites.rb +0 -56
  60. data/db/migrate/upgrade/20111109161550_update_roles.rb +0 -35
  61. data/db/migrate/upgrade/20111109161551_update_user.rb +0 -88
  62. data/db/migrate/upgrade/20120329161641_add_file_asset_indexes.rb +0 -22
  63. data/db/migrate/upgrade/20120517203052_add_queue_to_delayed_jobs.rb +0 -13
  64. data/db/migrate/upgrade/20120725205131_add_image_dimension_columns_to_file_asset.rb +0 -15
  65. data/lib/erp_tech_svcs/application_installer.rb +0 -102
  66. data/lib/erp_tech_svcs/utils/attachment_fu_patch.rb +0 -15
  67. data/lib/erp_tech_svcs/utils/compass_pdf.rb +0 -72
  68. data/lib/erp_tech_svcs/utils/pdf_processor.rb +0 -106
  69. data/spec/dummy/log/adam.log +0 -1
  70. data/spec/factories/role.rb +0 -5
  71. data/spec/models/role_spec.rb +0 -17
  72. data/spec/models/secured_model_spec.rb +0 -22
@@ -22,7 +22,7 @@ module ErpTechSvcs
22
22
  end
23
23
 
24
24
  def destroy
25
- message = "You have successfully logged out."
25
+ message = "You have logged out."
26
26
  logged_out_user_id = current_user.id unless current_user === false
27
27
  logout_to = session[:logout_to]
28
28
 
@@ -1,4 +1,6 @@
1
1
  class AttributeType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
2
4
  has_many :attribute_values, :dependent => :destroy
3
5
 
4
6
  validates_uniqueness_of :internal_identifier, :case_sensitive => false
@@ -1,4 +1,6 @@
1
1
  class AttributeValue < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
2
4
  belongs_to :attributed_record, :polymorphic => true
3
5
  belongs_to :attribute_type
4
6
 
@@ -1,4 +1,7 @@
1
1
  class AuditLog < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ attr_protected :created_at, :updated_at
2
5
 
3
6
  validates :party_id, :presence => {:message => 'cannot be blank'}
4
7
  validates :description, :presence => {:message => 'cannot be blank'}
@@ -18,7 +21,7 @@ class AuditLog < ActiveRecord::Base
18
21
  end
19
22
 
20
23
  #allow items to be looked up by method calls
21
- def respond_to?(m)
24
+ def respond_to?(m, include_private_methods = false)
22
25
  (super ? true : get_item_by_item_type_internal_identifier(m.to_s)) rescue super
23
26
  end
24
27
 
@@ -1,4 +1,6 @@
1
1
  class AuditLogItem < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
2
4
  belongs_to :audit_log_item_type
3
5
  belongs_to :audit_log
4
6
 
@@ -1,4 +1,6 @@
1
1
  class AuditLogItemType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
2
4
  acts_as_nested_set
3
5
  acts_as_erp_type
4
6
 
@@ -1,4 +1,6 @@
1
1
  class AuditLogType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
2
4
  acts_as_nested_set
3
5
  include ErpTechSvcs::Utils::DefaultNestedSetMethods
4
6
  acts_as_erp_type
@@ -1,5 +1,6 @@
1
1
  class Capability < ActiveRecord::Base
2
-
2
+ attr_protected :created_at, :updated_at
3
+
3
4
  belongs_to :scope_type
4
5
  belongs_to :capability_type
5
6
  belongs_to :capability_resource, :polymorphic => true
@@ -1,3 +1,5 @@
1
1
  class CapabilityType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+ attr_accessible :description, :internal_identifier
2
4
  has_many :capabilities
3
5
  end
@@ -0,0 +1,3 @@
1
+ Category.instance_eval do
2
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
3
+ end
@@ -0,0 +1,3 @@
1
+ CompassAeInstance.instance_eval do
2
+ has_file_assets
3
+ end
@@ -28,6 +28,8 @@ Paperclip.interpolates(:file_url){|data, style|
28
28
  }
29
29
 
30
30
  class FileAsset < ActiveRecord::Base
31
+ attr_protected :created_at, :updated_at
32
+
31
33
  if respond_to?(:class_attribute)
32
34
  class_attribute :file_type
33
35
  class_attribute :valid_extensions
@@ -272,7 +274,7 @@ class Pdf < TextFile
272
274
  self.valid_extensions = %w(.pdf .PDF)
273
275
  end
274
276
 
275
- class Swf < TextFile
277
+ class Swf < FileAsset
276
278
  self.file_type = :swf
277
279
  self.content_type = 'application/x-shockwave-flash'
278
280
  self.valid_extensions = %w(.swf .SWF)
data/app/models/group.rb CHANGED
@@ -8,6 +8,7 @@ class Group < ActiveRecord::Base
8
8
 
9
9
  has_one :party, :as => :business_party
10
10
 
11
+ attr_accessible :description
11
12
  validates_uniqueness_of :description, :case_sensitive => false
12
13
 
13
14
  def self.add(description)
@@ -26,7 +27,7 @@ class Group < ActiveRecord::Base
26
27
 
27
28
  def has_role?(role)
28
29
  role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
29
- all_roles.include?(role)
30
+ roles.include?(role)
30
31
  end
31
32
 
32
33
  def add_role(role)
@@ -139,29 +140,15 @@ class Group < ActiveRecord::Base
139
140
  end
140
141
 
141
142
  def role_class_capabilities
142
- scope_type = ScopeType.find_by_internal_identifier('class')
143
- Capability.joins(:capability_type).joins(:capability_accessors).
144
- where(:capability_accessors => { :capability_accessor_record_type => "SecurityRole" }).
145
- where("capability_accessor_record_id IN (#{roles.select('security_roles.id').to_sql})").
146
- where(:scope_type_id => scope_type.id)
143
+ roles.collect{|r| r.class_capabilities }.flatten.uniq.compact
147
144
  end
148
145
 
149
146
  def all_class_capabilities
150
- scope_type = ScopeType.find_by_internal_identifier('class')
151
- Capability.joins(:capability_type).joins(:capability_accessors).
152
- where("(capability_accessors.capability_accessor_record_type = 'Group' AND
153
- capability_accessor_record_id = (#{self.id})) OR
154
- (capability_accessors.capability_accessor_record_type = 'SecurityRole' AND
155
- capability_accessor_record_id IN (#{roles.select('security_roles.id').to_sql}))").
156
- where(:scope_type_id => scope_type.id)
157
- end
158
-
159
- def all_uniq_class_capabilities
160
- all_class_capabilities.all.uniq
147
+ (role_class_capabilities + class_capabilities).uniq
161
148
  end
162
149
 
163
150
  def class_capabilities_to_hash
164
- all_uniq_class_capabilities.map {|capability|
151
+ all_class_capabilities.map {|capability|
165
152
  { :capability_type_iid => capability.capability_type.internal_identifier,
166
153
  :capability_resource_type => capability.capability_resource_type
167
154
  }
@@ -1,4 +1,5 @@
1
1
  class ScopeType < ActiveRecord::Base
2
+ attr_accessible :description, :internal_identifier
2
3
 
3
4
  has_many :capabilities
4
5
 
@@ -8,6 +8,8 @@ class SecurityRole < ActiveRecord::Base
8
8
  validates_uniqueness_of :internal_identifier, :case_sensitive => false
9
9
  validates_length_of :internal_identifier, :within => 3..100
10
10
 
11
+ attr_accessible :description, :internal_identifier
12
+
11
13
  def to_xml(options = {})
12
14
  default_only = []
13
15
  options[:only] = (options[:only] || []) + default_only
data/app/models/user.rb CHANGED
@@ -41,15 +41,32 @@ class User < ActiveRecord::Base
41
41
  party.security_roles
42
42
  end
43
43
 
44
- def has_role?(role)
45
- role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
46
- all_roles.include?(role)
44
+ def has_role?(*passed_roles)
45
+ result = false
46
+ passed_roles.flatten!
47
+ passed_roles.each do |role|
48
+ role_iid = role.is_a?(SecurityRole) ? role.internal_identifier : role.to_s
49
+ all_roles.each do |this_role|
50
+ result = true if (this_role.internal_identifier == role_iid)
51
+ break if result
52
+ end
53
+ break if result
54
+ end
55
+ result
47
56
  end
48
57
 
49
58
  def add_role(role)
50
59
  party.add_role(role)
51
60
  end
52
61
 
62
+ def add_roles(*passed_roles)
63
+ party.add_roles(*passed_roles)
64
+ end
65
+
66
+ def remove_roles(*passed_roles)
67
+ party.remove_roles(*passed_roles)
68
+ end
69
+
53
70
  def remove_role(role)
54
71
  party.remove_role(role)
55
72
  end
@@ -86,70 +103,40 @@ class User < ActiveRecord::Base
86
103
 
87
104
  # roles assigned to the groups this user belongs to
88
105
  def group_roles
89
- SecurityRole.joins(:parties).
90
- where(:parties => {:business_party_type => 'Group'}).
91
- where("parties.business_party_id IN (#{groups.select('groups.id').to_sql})")
106
+ groups.collect{|g| g.roles }.flatten.uniq
92
107
  end
93
108
 
94
109
  # composite roles for this user
95
110
  def all_roles
96
- SecurityRole.joins(:parties).joins("LEFT JOIN users ON parties.id=users.party_id").
97
- where("(parties.business_party_type='Group' AND
98
- parties.business_party_id IN (#{groups.select('groups.id').to_sql})) OR
99
- (users.id=#{self.id})")
100
- end
101
-
102
- def all_uniq_roles
103
- all_roles.all.uniq
111
+ (group_roles + roles).uniq
104
112
  end
105
113
 
106
114
  def group_capabilities
107
- Capability.joins(:capability_type).joins(:capability_accessors).
108
- where(:capability_accessors => { :capability_accessor_record_type => "Group" }).
109
- where("capability_accessor_record_id IN (#{groups.select('groups.id').to_sql})")
115
+ groups.collect{|r| r.capabilities }.flatten.uniq.compact
110
116
  end
111
117
 
112
118
  def role_capabilities
113
- Capability.joins(:capability_type).joins(:capability_accessors).
114
- where(:capability_accessors => { :capability_accessor_record_type => "SecurityRole" }).
115
- where("capability_accessor_record_id IN (#{all_roles.select('security_roles.id').to_sql})")
119
+ all_roles.collect{|r| r.capabilities }.flatten.compact
116
120
  end
117
121
 
118
122
  def all_capabilities
119
- Capability.joins(:capability_type).joins(:capability_accessors).
120
- where("(capability_accessors.capability_accessor_record_type = 'Group' AND
121
- capability_accessor_record_id IN (#{groups.select('groups.id').to_sql})) OR
122
- (capability_accessors.capability_accessor_record_type = 'SecurityRole' AND
123
- capability_accessor_record_id IN (#{all_roles.select('security_roles.id').to_sql})) OR
124
- (capability_accessors.capability_accessor_record_type = 'User' AND
125
- capability_accessor_record_id = #{self.id})")
126
- end
127
-
128
- def all_uniq_capabilities
129
- all_capabilities.all.uniq
123
+ (role_capabilities + group_capabilities + capabilities).uniq
130
124
  end
131
125
 
132
126
  def group_class_capabilities
133
- scope_type = ScopeType.find_by_internal_identifier('class')
134
- group_capabilities.where(:scope_type_id => scope_type.id)
127
+ groups.collect{|g| g.class_capabilities }.flatten.uniq.compact
135
128
  end
136
129
 
137
130
  def role_class_capabilities
138
- scope_type = ScopeType.find_by_internal_identifier('class')
139
- role_capabilities.where(:scope_type_id => scope_type.id)
131
+ all_roles.collect{|r| r.class_capabilities }.flatten.uniq.compact
140
132
  end
141
133
 
142
134
  def all_class_capabilities
143
- scope_type = ScopeType.find_by_internal_identifier('class')
144
- all_capabilities.where(:scope_type_id => scope_type.id)
145
- end
146
-
147
- def all_uniq_class_capabilities
148
- all_class_capabilities.all.uniq
135
+ (role_class_capabilities + group_class_capabilities + class_capabilities).uniq
149
136
  end
150
137
 
151
138
  def class_capabilities_to_hash
152
- all_uniq_class_capabilities.map {|capability|
139
+ all_class_capabilities.map {|capability|
153
140
  { :capability_type_iid => capability.capability_type.internal_identifier,
154
141
  :capability_resource_type => capability.capability_resource_type
155
142
  }
@@ -6,7 +6,7 @@
6
6
  <body>
7
7
  <h1>Welcome <%= @user.username %></h1>
8
8
  <p>
9
- You have successfully registered, to activate your account follow this link: <a href="<%= @url %>"><%= @url %></a>.
9
+ You have successfully registered, to activate your account follow this link: <a href="<%= @url %>"><%= @url %></a>
10
10
  </p>
11
11
  <p>Your username is <%=@user.username%>, use the password you set during registration to login.</p>
12
12
  <p>Thanks for joining and have a great day!!</p>
@@ -7,7 +7,7 @@
7
7
  <h1>We have reset the password for, <%= @user.username %></h1>
8
8
  <p>
9
9
  The new password is <%= @user.password_confirmation %>.
10
- To login and update your password follow this link: <a href="<%= @url %>"><%= @url %></a>.
10
+ To login and update your password follow this link: <a href="<%= @url %>"><%= @url %></a>
11
11
  </p>
12
12
  <p>Thanks for being a member and have a great day!</p>
13
13
  </body>
@@ -2,7 +2,9 @@ Rails.application.config.erp_tech_svcs.configure do |config|
2
2
  config.installation_domain = 'localhost:3000'
3
3
  config.login_url = '/erp_app/login'
4
4
  config.email_notifications_from = 'notifications@noreply.com'
5
+ config.email_regex = "^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$"
5
6
  config.max_file_size_in_mb = 5
7
+ config.file_upload_types = 'txt,pdf,zip,tgz,gz,rar,jpg,jpeg,gif,png,tif,tiff,bmp,csv,xls,xlsx,doc,docx,ppt,pptx,psd,ai,css,js,mp3,mp4,m4a,m4v,mov,wav,wmv'
6
8
  config.file_assets_location = 'file_assets' # relative to Rails.root/
7
9
  config.s3_url_expires_in_seconds = 60
8
10
  config.s3_protocol = 'https' # Can be either 'http' or 'https'
@@ -2,8 +2,8 @@ class NoteCapabilities
2
2
 
3
3
  def self.up
4
4
  #insert data here
5
- admin = SecurityRole.find_by_internal_identifier('admin')
6
- employee = SecurityRole.find_by_internal_identifier('employee')
5
+ admin = SecurityRole.find_or_create_by_description_and_internal_identifier(:description => 'Admin', :internal_identifier => 'admin')
6
+ employee = SecurityRole.find_or_create_by_description_and_internal_identifier(:description => 'Employee', :internal_identifier => 'employee')
7
7
 
8
8
  admin.add_capability('create', 'Note')
9
9
  admin.add_capability('delete', 'Note')
@@ -258,9 +258,9 @@ class BaseTechServices < ActiveRecord::Migration
258
258
  # check that each table exists before trying to delete it.
259
259
  [ :groups,
260
260
  :audit_logs, :sessions, :simple_captcha_data,
261
- :capable_models, :capability_types, :capabilities,:capabilities_capable_models,
262
- :roles_users, :roles, :audit_log_items, :audit_log_item_types,
263
- :users, :secured_models, :roles_secured_models, :file_assets, :delayed_jobs
261
+ :capability_accessors, :capability_types, :capabilities,:scope_types,
262
+ :parties_security_roles, :roles, :audit_log_items, :audit_log_item_types,
263
+ :users, :file_assets, :delayed_jobs
264
264
  ].each do |tbl|
265
265
  if table_exists?(tbl)
266
266
  drop_table tbl
@@ -3,9 +3,11 @@ module ErpTechSvcs
3
3
  class << self
4
4
 
5
5
  attr_accessor :max_file_size_in_mb,
6
+ :file_upload_types,
6
7
  :installation_domain,
7
8
  :login_url,
8
9
  :email_notifications_from,
10
+ :email_regex,
9
11
  :file_assets_location,
10
12
  :s3_url_expires_in_seconds,
11
13
  :s3_protocol,
@@ -17,9 +19,11 @@ module ErpTechSvcs
17
19
  def init!
18
20
  @defaults = {
19
21
  :@max_file_size_in_mb => 5,
22
+ :@file_upload_types => 'txt,pdf,zip,tgz,gz,rar,jpg,jpeg,gif,png,tif,tiff,bmp,csv,xls,xlsx,doc,docx,ppt,pptx,psd,ai,css,js,mp3,mp4,m4a,m4v,mov,wav,wmv',
20
23
  :@installation_domain => 'localhost:3000',
21
24
  :@login_url => '/erp_app/login',
22
25
  :@email_notifications_from => 'notifications@noreply.com',
26
+ :@email_regex => "^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$",
23
27
  :@file_assets_location => 'file_assets', # relative to Rails.root/
24
28
  :@s3_url_expires_in_seconds => 60,
25
29
  :@s3_protocol => 'https', # Can be either 'http' or 'https'
@@ -249,7 +249,7 @@ module ActiveRecord #:nodoc:
249
249
 
250
250
  versioned_class.cattr_accessor :original_class
251
251
  versioned_class.original_class = self
252
- versioned_class.set_table_name versioned_table_name
252
+ versioned_class.table_name = versioned_table_name
253
253
  versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
254
254
  :class_name => "::#{self.to_s}",
255
255
  :foreign_key => versioned_foreign_key
@@ -268,134 +268,133 @@ module ActiveRecord #:nodoc:
268
268
  after_save :clear_old_versions
269
269
  end
270
270
 
271
- module InstanceMethods
272
- # Saves a version of the model in the versioned table. This is called in the after_save callback by default
273
- def save_version
274
- if @saving_version
275
- @saving_version = nil
276
- rev = self.class.versioned_class.new
277
- clone_versioned_model(self, rev)
278
- rev.send("#{self.class.version_column}=", send(self.class.version_column))
279
- rev.send("#{self.class.versioned_foreign_key}=", id)
280
- rev.save
281
- end
271
+ # INSTANCE METHODS
272
+ # Saves a version of the model in the versioned table. This is called in the after_save callback by default
273
+ def save_version
274
+ if @saving_version
275
+ @saving_version = nil
276
+ rev = self.class.versioned_class.new
277
+ clone_versioned_model(self, rev)
278
+ rev.send("#{self.class.version_column}=", send(self.class.version_column))
279
+ rev.send("#{self.class.versioned_foreign_key}=", id)
280
+ rev.save
282
281
  end
282
+ end
283
283
 
284
- # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
285
- # Override this method to set your own criteria for clearing old versions.
286
- def clear_old_versions
287
- return if self.class.max_version_limit == 0
288
- excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
289
- if excess_baggage > 0
290
- self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
291
- end
284
+ # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
285
+ # Override this method to set your own criteria for clearing old versions.
286
+ def clear_old_versions
287
+ return if self.class.max_version_limit == 0
288
+ excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
289
+ if excess_baggage > 0
290
+ self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
292
291
  end
292
+ end
293
293
 
294
- # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
295
- def revert_to(version)
296
- if version.is_a?(self.class.versioned_class)
297
- return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
298
- else
299
- return false unless version = versions.where(self.class.version_column => version).first
300
- end
301
- self.clone_versioned_model(version, self)
302
- send("#{self.class.version_column}=", version.send(self.class.version_column))
303
- true
294
+ # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
295
+ def revert_to(version)
296
+ if version.is_a?(self.class.versioned_class)
297
+ return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
298
+ else
299
+ return false unless version = versions.where(self.class.version_column => version).first
304
300
  end
301
+ self.clone_versioned_model(version, self)
302
+ send("#{self.class.version_column}=", version.send(self.class.version_column))
303
+ true
304
+ end
305
305
 
306
- # Reverts a model to a given version and saves the model.
307
- # Takes either a version number or an instance of the versioned model
308
- def revert_to!(version)
309
- revert_to(version) ? save_without_revision : false
310
- end
306
+ # Reverts a model to a given version and saves the model.
307
+ # Takes either a version number or an instance of the versioned model
308
+ def revert_to!(version)
309
+ revert_to(version) ? save_without_revision : false
310
+ end
311
311
 
312
- # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
313
- def save_without_revision
314
- save_without_revision!
315
- true
316
- rescue
317
- false
318
- end
312
+ # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
313
+ def save_without_revision
314
+ save_without_revision!
315
+ true
316
+ rescue
317
+ false
318
+ end
319
319
 
320
- def save_without_revision!
321
- without_locking do
322
- without_revision do
323
- save!
324
- end
320
+ def save_without_revision!
321
+ without_locking do
322
+ without_revision do
323
+ save!
325
324
  end
326
325
  end
326
+ end
327
327
 
328
- def altered?
329
- track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
330
- end
331
-
332
- # Clones a model. Used when saving a new version or reverting a model's version.
333
- def clone_versioned_model(orig_model, new_model)
334
- self.class.versioned_columns.each do |col|
335
- new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
336
- end
328
+ def altered?
329
+ track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
330
+ end
337
331
 
338
- if orig_model.is_a?(self.class.versioned_class)
339
- new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
340
- elsif new_model.is_a?(self.class.versioned_class)
341
- new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
342
- end
332
+ # Clones a model. Used when saving a new version or reverting a model's version.
333
+ def clone_versioned_model(orig_model, new_model)
334
+ self.class.versioned_columns.each do |col|
335
+ new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
343
336
  end
344
337
 
345
- # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
346
- def save_version?
347
- version_condition_met? && altered?
338
+ if orig_model.is_a?(self.class.versioned_class)
339
+ new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
340
+ elsif new_model.is_a?(self.class.versioned_class)
341
+ new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
348
342
  end
343
+ end
349
344
 
350
- # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
351
- # custom version condition checking.
352
- def version_condition_met?
353
- case
354
- when version_condition.is_a?(Symbol)
355
- send(version_condition)
356
- when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
357
- version_condition.call(self)
358
- else
359
- version_condition
360
- end
361
- end
345
+ # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
346
+ def save_version?
347
+ version_condition_met? && altered?
348
+ end
362
349
 
363
- # Executes the block with the versioning callbacks disabled.
364
- #
365
- # @foo.without_revision do
366
- # @foo.save
367
- # end
368
- #
369
- def without_revision(&block)
370
- self.class.without_revision(&block)
350
+ # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
351
+ # custom version condition checking.
352
+ def version_condition_met?
353
+ case
354
+ when version_condition.is_a?(Symbol)
355
+ send(version_condition)
356
+ when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
357
+ version_condition.call(self)
358
+ else
359
+ version_condition
371
360
  end
361
+ end
372
362
 
373
- # Turns off optimistic locking for the duration of the block
374
- #
375
- # @foo.without_locking do
376
- # @foo.save
377
- # end
378
- #
379
- def without_locking(&block)
380
- self.class.without_locking(&block)
381
- end
363
+ # Executes the block with the versioning callbacks disabled.
364
+ #
365
+ # @foo.without_revision do
366
+ # @foo.save
367
+ # end
368
+ #
369
+ def without_revision(&block)
370
+ self.class.without_revision(&block)
371
+ end
382
372
 
383
- def empty_callback()
384
- end
373
+ # Turns off optimistic locking for the duration of the block
374
+ #
375
+ # @foo.without_locking do
376
+ # @foo.save
377
+ # end
378
+ #
379
+ def without_locking(&block)
380
+ self.class.without_locking(&block)
381
+ end
385
382
 
386
- #:nodoc:
383
+ def empty_callback()
384
+ end
387
385
 
388
- protected
389
- # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
390
- def set_new_version
391
- @saving_version = new_record? || save_version?
392
- self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
393
- end
386
+ #:nodoc:
394
387
 
395
- # Gets the next available version for the current record, or 1 for a new record
396
- def next_version
397
- (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
398
- end
388
+ protected
389
+ # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
390
+ def set_new_version
391
+ @saving_version = new_record? || save_version?
392
+ self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
393
+ end
394
+
395
+ # Gets the next available version for the current record, or 1 for a new record
396
+ def next_version
397
+ (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
399
398
  end
400
399
 
401
400
  module ClassMethods