diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed0a8dc4..4f5bf267 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,8 @@ jobs: - rails70 - rails71 - rails72 + - rails80 + - rails_main db: [POSTGRES, MYSQL, SQLITE] exclude: # MySQL has issues on Ruby 2.3 @@ -98,6 +100,38 @@ jobs: - appraisal: rails72 ruby: "3.0" + # Rails 8.0 supports Ruby 3.2+ + - appraisal: rails80 + ruby: "2.3" + - appraisal: rails80 + ruby: "2.4" + - appraisal: rails80 + ruby: "2.5" + - appraisal: rails80 + ruby: "2.6" + - appraisal: rails80 + ruby: "2.7" + - appraisal: rails80 + ruby: "3.0" + - appraisal: rails80 + ruby: "3.1" + + # Rails main supports Ruby 3.2+ + - appraisal: rails_main + ruby: "2.3" + - appraisal: rails_main + ruby: "2.4" + - appraisal: rails_main + ruby: "2.5" + - appraisal: rails_main + ruby: "2.6" + - appraisal: rails_main + ruby: "2.7" + - appraisal: rails_main + ruby: "3.0" + - appraisal: rails_main + ruby: "3.1" + services: postgres: image: postgres diff --git a/Appraisals b/Appraisals index 6df14d46..d23f3ef0 100644 --- a/Appraisals +++ b/Appraisals @@ -44,3 +44,17 @@ appraise "rails72" do gem "pg", "~> 1.1" gem "sqlite3", ">= 1.4" end + +appraise "rails80" do + gem "rails", "~> 8.0.0" + gem "mysql2", "~> 0.5" + gem "pg", "~> 1.1" + gem "sqlite3", ">= 1.4" +end + +appraise "rails_main" do + gem "rails", github: "rails/rails", branch: "main" + gem "mysql2", "~> 0.5" + gem "pg", "~> 1.1" + gem "sqlite3", ">= 2.0" +end diff --git a/CHANGELOG.md b/CHANGELOG.md index d470758a..6395c14f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Audited ChangeLog +### 5.8.0 (2024-11-08) +- Allow calling audited multiple times - @mohammednasser-32 + [734](https://github.com/collectiveidea/audited/pull/734) +- Relax gemspec to allow Rails 8.1 - @BranLiang + [738](https://github.com/collectiveidea/audited/pull/738) + ### 5.7.0 (2024-08-13) - Support for Rails 7.2 and Ruby 3.3, and testing cleanups - @mattbrictson diff --git a/audited.gemspec b/audited.gemspec index bc1b17ff..386cdf67 100644 --- a/audited.gemspec +++ b/audited.gemspec @@ -16,11 +16,11 @@ Gem::Specification.new do |gem| gem.required_ruby_version = ">= 2.3.0" - gem.add_dependency "activerecord", ">= 5.2", "< 8.0" - gem.add_dependency "activesupport", ">= 5.2", "< 8.0" + gem.add_dependency "activerecord", ">= 5.2", "< 8.2" + gem.add_dependency "activesupport", ">= 5.2", "< 8.2" gem.add_development_dependency "appraisal" - gem.add_development_dependency "rails", ">= 5.2", "< 8.0" + gem.add_development_dependency "rails", ">= 5.2", "< 8.2" gem.add_development_dependency "rspec-rails" gem.add_development_dependency "standard" gem.add_development_dependency "single_cov" diff --git a/gemfiles/rails80.gemfile b/gemfiles/rails80.gemfile new file mode 100644 index 00000000..2942329f --- /dev/null +++ b/gemfiles/rails80.gemfile @@ -0,0 +1,10 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rails", "~> 8.0.0" +gem "mysql2", "~> 0.5" +gem "pg", "~> 1.1" +gem "sqlite3", ">= 1.4" + +gemspec name: "audited", path: "../" diff --git a/gemfiles/rails_main.gemfile b/gemfiles/rails_main.gemfile new file mode 100644 index 00000000..c0bd890a --- /dev/null +++ b/gemfiles/rails_main.gemfile @@ -0,0 +1,10 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rails", github: "rails/rails", branch: "main" +gem "mysql2", "~> 0.5" +gem "pg", "~> 1.1" +gem "sqlite3", ">= 2.0" + +gemspec name: "audited", path: "../" diff --git a/lib/audited/auditor.rb b/lib/audited/auditor.rb index c9c867ae..a164f72a 100644 --- a/lib/audited/auditor.rb +++ b/lib/audited/auditor.rb @@ -59,9 +59,16 @@ module ClassMethods # end # def audited(options = {}) - # don't allow multiple calls - return if included_modules.include?(Audited::Auditor::AuditedInstanceMethods) + audited? ? update_audited_options(options) : set_audit(options) + end + + private + + def audited? + included_modules.include?(Audited::Auditor::AuditedInstanceMethods) + end + def set_audit(options) extend Audited::Auditor::AuditedClassMethods include Audited::Auditor::AuditedInstanceMethods @@ -69,10 +76,7 @@ def audited(options = {}) class_attribute :audited_options, instance_writer: false attr_accessor :audit_version, :audit_comment - self.audited_options = options - normalize_audited_options - - self.audit_associated_with = audited_options[:associated_with] + set_audited_options(options) if audited_options[:comment_required] validate :presence_of_audit_comment @@ -100,6 +104,18 @@ def audited(options = {}) def has_associated_audits has_many :associated_audits, as: :associated, class_name: Audited.audit_class.name end + + def update_audited_options(new_options) + previous_audit_options = self.audited_options + set_audited_options(new_options) + self.reset_audited_columns + end + + def set_audited_options(options) + self.audited_options = options + normalize_audited_options + self.audit_associated_with = audited_options[:associated_with] + end end module AuditedInstanceMethods @@ -530,6 +546,11 @@ def calculate_non_audited_columns def class_auditing_enabled Audited.store.fetch("#{table_name}_auditing_enabled", true) end + + def reset_audited_columns + @audited_columns = nil + @non_audited_columns = nil + end end end end diff --git a/lib/audited/version.rb b/lib/audited/version.rb index 54c7f198..4e622287 100644 --- a/lib/audited/version.rb +++ b/lib/audited/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Audited - VERSION = "5.7.0" + VERSION = "5.8.0" end diff --git a/spec/audited/auditor_spec.rb b/spec/audited/auditor_spec.rb index cff4044b..15ff2f77 100644 --- a/spec/audited/auditor_spec.rb +++ b/spec/audited/auditor_spec.rb @@ -1270,4 +1270,20 @@ def stub_global_max_audits(max_audits) }.to_not change(Audited::Audit, :count) end end + + describe "call audit multiple times" do + it "should update audit options" do + user = Models::ActiveRecord::UserOnlyName.create + user.update(password: "new password 1", name: "new name 1") + expect(user.audits.last.audited_changes.keys).to eq(%w[name]) + + user.class.class_eval do + audited only: :password + end + + user = Models::ActiveRecord::UserOnlyName.last + user.update(password: "new password 2", name: "new name 2") + expect(user.audits.last.audited_changes.keys).to eq(%w[password]) + end + end end diff --git a/spec/rails_app/config/application.rb b/spec/rails_app/config/application.rb index 6de73c8e..a485f848 100644 --- a/spec/rails_app/config/application.rb +++ b/spec/rails_app/config/application.rb @@ -33,6 +33,10 @@ class Application < Rails::Application if Rails.gem_version >= Gem::Version.new("7.1") config.active_support.cache_format_version = 7.1 end + + if Rails.gem_version >= Gem::Version.new("8.0.0.alpha") + config.active_support.to_time_preserves_timezone = :zone + end end end diff --git a/spec/support/active_record/models.rb b/spec/support/active_record/models.rb index 34dde868..53b57863 100644 --- a/spec/support/active_record/models.rb +++ b/spec/support/active_record/models.rb @@ -36,6 +36,12 @@ class UserOnlyPassword < ::ActiveRecord::Base audited only: :password end + class UserOnlyName < ::ActiveRecord::Base + self.table_name = :users + attribute :non_column_attr if Rails.gem_version >= Gem::Version.new("5.1") + audited only: :name + end + class UserRedactedPassword < ::ActiveRecord::Base self.table_name = :users audited redacted: :password