erp_tech_svcs 3.0.12 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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