Class: PaperTrailHistory::VersionService
- Inherits:
-
Object
- Object
- PaperTrailHistory::VersionService
- Defined in:
- app/models/paper_trail_history/version_service.rb
Overview
Queries and restores PaperTrail versions for the interface.
The class knows about applications with more than one version table: it
resolves the version class through TrackableModel instead of assuming
PaperTrail::Version.
Constant Summary collapse
- SEARCH_TERM_LIMIT =
The longest search text that the engine sends to the database. A longer text costs time and gives no better result.
100- SEARCH_ESCAPE_CHARACTER =
Marks a wildcard of the user as a normal character. A backslash would need its own escaping in each database, this character does not.
'!'- LOCK =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Guards the cache. A Monitor is reentrant, thus the discovery can reach this class again without a deadlock.
Monitor.new
Class Method Summary collapse
-
.all_version_classes ⇒ Array<Class>
Every version class that the application uses.
-
.available_events(model_name = nil) ⇒ Array<String>
The different events that appear in the versions.
-
.clear_cache! ⇒ Object
Clears the cached version classes.
-
.find_version(version_id, model_name = nil) ⇒ ActiveRecord::Base?
Finds one version.
-
.for_model(model_name, params = {}) ⇒ ActiveRecord::Relation
The versions of one model, newest first.
-
.for_record(model_name, item_id, params = {}) ⇒ ActiveRecord::Relation
The versions of one record, newest first.
-
.restore_version(version) ⇒ Hash
Restores a record to the state of the given version.
-
.unique_whodunnits(model_name = nil) ⇒ Array<String>
The different people that appear in the versions.
Class Method Details
.all_version_classes ⇒ Array<Class>
Every version class that the application uses.
The result comes from a cache. clear_cache! empties it.
180 181 182 |
# File 'app/models/paper_trail_history/version_service.rb', line 180 def self.all_version_classes @all_version_classes || LOCK.synchronize { @all_version_classes ||= discover_version_classes } end |
.available_events(model_name = nil) ⇒ Array<String>
The different events that appear in the versions.
122 123 124 |
# File 'app/models/paper_trail_history/version_service.rb', line 122 def self.available_events(model_name = nil) distinct_column_values(:event, model_name) end |
.clear_cache! ⇒ Object
Clears the cached version classes. The engine calls this on each code reload, because the cache holds class objects that a reload replaces.
192 193 194 |
# File 'app/models/paper_trail_history/version_service.rb', line 192 def self.clear_cache! LOCK.synchronize { @all_version_classes = nil } end |
.find_version(version_id, model_name = nil) ⇒ ActiveRecord::Base?
Finds one version.
Give the model name whenever you have it. Without it the method looks in every version table, and an ID is not unique over more than one table.
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/paper_trail_history/version_service.rb', line 67 def self.find_version(version_id, model_name = nil) if model_name.present? # Direct query when model_name is known (fast) trackable_model = TrackableModel.find(model_name) return nil unless trackable_model trackable_model.version_class.unscoped.find_by(id: version_id) else # Fall back to searching across all tables (backwards compatible) find_version_across_tables(version_id) end end |
.for_model(model_name, params = {}) ⇒ ActiveRecord::Relation
The versions of one model, newest first.
33 34 35 36 37 38 39 |
# File 'app/models/paper_trail_history/version_service.rb', line 33 def self.for_model(model_name, params = {}) trackable_model = TrackableModel.find(model_name) return PaperTrail::Version.none unless trackable_model versions = base_versions_for_model(trackable_model) apply_filters(versions, params).order(created_at: :desc) end |
.for_record(model_name, item_id, params = {}) ⇒ ActiveRecord::Relation
The versions of one record, newest first.
51 52 53 54 55 56 57 |
# File 'app/models/paper_trail_history/version_service.rb', line 51 def self.for_record(model_name, item_id, params = {}) trackable_model = TrackableModel.find(model_name) return PaperTrail::Version.none unless trackable_model versions = base_versions_for_record(trackable_model, item_id) apply_record_filters(versions, params).order(created_at: :desc) end |
.restore_version(version) ⇒ Hash
Restores a record to the state of the given version.
Give the version record itself whenever you have it. An ID alone is not
unique: an application with more than one version table (PaperTrail's
versions plus a custom class such as ProductVersion) can hold the same
ID in each table, and a search by ID finds whichever table comes first.
PaperTrail keeps the previous state of a record as YAML. Rails loads only
permitted classes from a YAML column, thus the host application has to list
the types that its models use in
config.active_record.yaml_column_permitted_classes. If a class is
missing, this method gives back an error that names the setting.
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/models/paper_trail_history/version_service.rb', line 96 def self.restore_version(version) version = find_version_across_tables(version) unless version.is_a?(ActiveRecord::Base) return validate_version_for_restore(version) unless version_restorable?(version) perform_version_restore(version) rescue Psych::DisallowedClass => e { success: false, error: I18n.t('paper_trail_history.errors.yaml_class_not_permitted', message: e.) } rescue StandardError => e { success: false, error: e. } end |
.unique_whodunnits(model_name = nil) ⇒ Array<String>
The different people that appear in the versions.
114 115 116 |
# File 'app/models/paper_trail_history/version_service.rb', line 114 def self.unique_whodunnits(model_name = nil) distinct_column_values(:whodunnit, model_name) end |