immosquare-active-record-change-tracker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 299d11653d5c906ae788ed7b915a9b5570c056cdb7e43d16ae7e3bbeafab857e
4
+ data.tar.gz: 9bc986bd135035ec0e9708a7bef80e678c8b69f764b5781644e9a8c9c98f87b8
5
+ SHA512:
6
+ metadata.gz: 99002bc0bc01c7d4cafff14310e5942c00298ee8d3781414cd13d6f17fa8a53e8b84c98ca13a78a4c123a7f9a06a7f61396f9337cefea5fa026391b3e5c6721e
7
+ data.tar.gz: b24bca711330f70cb77f59d6929bdc87de2244f655f9e548e87c993a12dde6b05235b7da115be1acdec940cce11aa46195662531f3c6e8c32a29e5f6e0d912b7
@@ -0,0 +1,36 @@
1
+ require "rails/generators"
2
+ require "rails/generators/migration"
3
+
4
+
5
+ module ImmosquareActiveRecordChangeTracker
6
+ class InstallGenerator < Rails::Generators::Base
7
+
8
+ include Rails::Generators::Migration
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Generate migration for Table ActiveRecordChangeTracker"
13
+
14
+ def copy_migration
15
+ migration_template("template_1.rb", "db/migrate/#{migration_name.underscore}.rb", :migration_version => migration_version)
16
+ end
17
+
18
+ def self.next_migration_number(dirname)
19
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
20
+ end
21
+
22
+ private
23
+
24
+
25
+ def migration_name
26
+ "CreateActiveRecordChangeTracker"
27
+ end
28
+
29
+ def migration_version
30
+ return if ActiveRecord::VERSION::MAJOR < 6
31
+
32
+ "[#{ActiveRecord::VERSION::STRING.to_f}]"
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ class <%= "#{migration_name} < ActiveRecord::Migration#{migration_version}" %>
2
+
3
+ def change
4
+ create_table(:active_record_change_trackers) do |t|
5
+ t.references(:recordable, :polymorphic => true, :foreign_key => false, :index => false, :null => false)
6
+ t.references(:modifier, :polymorphic => true, :foreign_key => false, :index => false, :null => true)
7
+ t.string(:event, :null => true, :limit => 10)
8
+ t.text(:data, :null => true, :limit => 4_294_967_295)
9
+ t.datetime(:created_at, :null => false)
10
+ end
11
+
12
+ add_index(:active_record_change_trackers, [:recordable_type, :recordable_id])
13
+ add_index(:active_record_change_trackers, [:modifier_type, :modifier_id])
14
+ end
15
+
16
+ end
@@ -0,0 +1,15 @@
1
+ module ImmosquareActiveRecordChangeTracker
2
+ ##============================================================##
3
+ ## On nome le modèle différemment que ApplicationRecordHistory
4
+ ## pour éviter les conflits avec le nom du module.
5
+ ##============================================================##
6
+ class HistoryRecord < ::ActiveRecord::Base
7
+
8
+ self.table_name = "active_record_change_trackers"
9
+
10
+ belongs_to :recordable, :polymorphic => true
11
+ belongs_to :modifier, :polymorphic => true
12
+ serialize :data, :coder => JSON
13
+
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require "rails"
2
+
3
+ module ImmosquareActiveRecordChangeTracker
4
+ class Railtie < Rails::Railtie
5
+
6
+ initializer "immosquare_active_record_change_tracker.active_record" do
7
+ ActiveSupport.on_load(:active_record) do
8
+ ##============================================================##
9
+ ## Pour ajouter une gestion de l'historique des modifications
10
+ ##============================================================##
11
+ extend ImmosquareActiveRecordChangeTracker::ClassMethods
12
+
13
+ ##============================================================##
14
+ ## Définir la classe HistoryRecord après le chargement d'ActiveRecord
15
+ ##============================================================##
16
+ require "immosquare-active-record-change-tracker/models/history_record"
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module ImmosquareActiveRecordChangeTracker
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,136 @@
1
+ ##============================================================##
2
+ ## Rails
3
+ ##============================================================##
4
+ require_relative "immosquare-active-record-change-tracker/railtie"
5
+ require_relative "generators/immosquare-active-record-change-tracker/install/install_generator"
6
+
7
+
8
+ module ImmosquareActiveRecordChangeTracker
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+ def track_active_record_changes(options = {}, &modifier_block)
13
+ ##============================================================##
14
+ ## Inclut les méthodes d'instance nécessaires
15
+ ##============================================================##
16
+ include(ImmosquareActiveRecordChangeTracker::InstanceMethods)
17
+
18
+ ##============================================================##
19
+ ## Stocker les options dans un attribut de classe
20
+ ##============================================================##
21
+ class_attribute(:history_options)
22
+ self.history_options = options
23
+
24
+ ##============================================================##
25
+ ## Stocker le bloc du modificateur s'il est fourni
26
+ ##============================================================##
27
+ history_options[:modifier_block] = modifier_block if block_given?
28
+
29
+ ##============================================================##
30
+ ## Configure le callback after_save
31
+ ##============================================================##
32
+ after_save(:save_change_history)
33
+ after_destroy(:delete_change_history)
34
+ end
35
+ end
36
+
37
+ module InstanceMethods
38
+ private
39
+
40
+ ##============================================================##
41
+ ## Stocker les changements après un create ou save ou update
42
+ ##============================================================##
43
+ def save_change_history
44
+ history_options = self.class.history_options
45
+
46
+ ##============================================================##
47
+ ## Récupérer les champs à observer
48
+ ##============================================================##
49
+ changes_to_save =
50
+ if history_options[:only].present?
51
+ previous_changes.slice(*history_options[:only].map(&:to_s))
52
+ else
53
+ excluded_fields = history_options[:except] || []
54
+ excluded_fields += [:created_at, :updated_at]
55
+ previous_changes.except(*excluded_fields.uniq.map(&:to_s))
56
+ end
57
+
58
+
59
+ ##============================================================##
60
+ ## Gestion de Globalize
61
+ ##============================================================##
62
+ if respond_to?(:translated_attribute_names)
63
+ translated_attribute_names = send(:translated_attribute_names).map(&:to_sym)
64
+ globalize_changes = {}
65
+
66
+ translations.each do |translation|
67
+ locale = translation.locale.to_sym
68
+ translation.previous_changes.each do |attribute, values|
69
+ attribute = attribute.to_sym
70
+ next if !attribute.in?(translated_attribute_names)
71
+
72
+ old_value, new_value = values
73
+ ##============================================================##
74
+ ## On ne sauvegarde pas les changements si les valeurs sont identiques
75
+ ## ou si on passe de nil à "" ou de "" à nil
76
+ ##============================================================##
77
+ next if old_value == new_value || (old_value.blank? && new_value.blank?)
78
+
79
+ globalize_changes[attribute] ||= {}
80
+ globalize_changes[attribute][locale] = [old_value, new_value]
81
+ end
82
+ end
83
+ changes_to_save.merge!(globalize_changes)
84
+ end
85
+
86
+
87
+ ##============================================================##
88
+ ## Si aucun changement à sauvegarder, on sort
89
+ ##============================================================##
90
+ return if changes_to_save.none?
91
+
92
+ ##============================================================##
93
+ ## Récupéreration du modificateur en exécutant le bloc s'il est défini
94
+ ##============================================================##
95
+ modifier = history_options[:modifier_block]&.call
96
+
97
+ ##============================================================##
98
+ ## Gestion de l'event
99
+ ##============================================================##
100
+ event = previously_new_record? ? "create" : "update"
101
+
102
+ ##============================================================##
103
+ ## On crée un enregistrement dans la table d'historique
104
+ ##============================================================##
105
+ ImmosquareActiveRecordChangeTracker::HistoryRecord.create!(
106
+ :recordable => self,
107
+ :modifier => modifier,
108
+ :data => changes_to_save,
109
+ :event => event,
110
+ :created_at => DateTime.now
111
+ )
112
+ end
113
+
114
+ ##============================================================##
115
+ ## Stocker l'évenement destroy
116
+ ## Pas besoin de data, rien n'a changé.
117
+ ##============================================================##
118
+ def delete_change_history
119
+ ##============================================================##
120
+ ## Récupéreration du modificateur en exécutant le bloc s'il est défini
121
+ ##============================================================##
122
+ modifier = history_options[:modifier_block]&.call
123
+
124
+ ##============================================================##
125
+ ## On crée un enregistrement dans la table d'historique
126
+ ##============================================================##
127
+ ImmosquareActiveRecordChangeTracker::HistoryRecord.create!(
128
+ :recordable => self,
129
+ :modifier => modifier,
130
+ :data => nil,
131
+ :event => "destroy",
132
+ :created_at => DateTime.now
133
+ )
134
+ end
135
+ end
136
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: immosquare-active-record-change-tracker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - IMMO SQUARE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-10-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem to track changes on ActiveRecord models
14
+ email:
15
+ - jules@immosquare.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/generators/immosquare-active-record-change-tracker/install/install_generator.rb
21
+ - lib/generators/immosquare-active-record-change-tracker/install/templates/template_1.rb
22
+ - lib/immosquare-active-record-change-tracker.rb
23
+ - lib/immosquare-active-record-change-tracker/models/history_record.rb
24
+ - lib/immosquare-active-record-change-tracker/railtie.rb
25
+ - lib/immosquare-active-record-change-tracker/version.rb
26
+ homepage: https://github.com/IMMOSQUARE/immosquare-active-record-change-tracker
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 2.7.2
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.5.11
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: ActiveRecord Change Tracker
49
+ test_files: []