Class: DecisionAgent::Versioning::ActiveRecordAdapter
Overview
ActiveRecord-based version storage adapter for Rails applications
Requires ActiveRecord models to be set up in the Rails app
Constant Summary
StatusValidator::VALID_STATUSES
Instance Method Summary
collapse
#validate_status!
Methods inherited from Adapter
#compare_versions
Constructor Details
Returns a new instance of ActiveRecordAdapter.
13
14
15
16
17
18
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 13
def initialize
return if defined?(ActiveRecord)
raise DecisionAgent::ConfigurationError,
"ActiveRecord is not available. Please ensure Rails/ActiveRecord is loaded."
end
|
Instance Method Details
#activate_version(version_id:) ⇒ Object
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 93
def activate_version(version_id:)
retry_with_backoff(max_retries: 10) do
version = nil
rule_version_class.transaction do
version = rule_version_class.lock.find(version_id)
rule_version_class.where(rule_id: version.rule_id, status: "active")
.where.not(id: version_id)
.update_all(status: "archived")
version.update!(status: "active")
end
serialize_version(version)
end
end
|
#create_tag(model_id:, version_id:, name:) ⇒ Object
Create (or update) a named tag pointing to a specific version.
Tags are unique per model; calling this with an existing name re-points the tag.
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 136
def create_tag(model_id:, version_id:, name:)
raise DecisionAgent::ValidationError, "Tag name cannot be blank" if name.nil? || name.to_s.strip.empty?
raise DecisionAgent::NotFoundError, "Version not found: #{version_id}" unless get_version(version_id: version_id)
retry_with_backoff(max_retries: 10) do
tag = nil
rule_version_tag_class.transaction do
existing = rule_version_tag_class.find_by(model_id: model_id, name: name)
if existing
existing.update!(version_id: version_id)
tag = existing.reload
else
tag = rule_version_tag_class.create!(model_id: model_id, name: name, version_id: version_id)
end
end
serialize_tag(tag)
end
end
|
#create_version(rule_id:, content:, metadata: {}) ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 20
def create_version(rule_id:, content:, metadata: {})
status = metadata[:status] || "active"
validate_status!(status)
retry_with_backoff(max_retries: 10) do
version = nil
rule_version_class.transaction do
last_version = rule_version_class.where(rule_id: rule_id)
.order(version_number: :desc)
.lock
.first
next_version_number = last_version ? last_version.version_number + 1 : 1
rule_version_class.where(rule_id: rule_id, status: "active")
.update_all(status: "archived")
version = rule_version_class.create!(
rule_id: rule_id,
version_number: next_version_number,
content: content.to_json,
created_by: metadata[:created_by] || "system",
changelog: metadata[:changelog] || "Version #{next_version_number}",
status: status
)
end
serialize_version(version)
end
end
|
#delete_tag(model_id:, name:) ⇒ Object
Delete a tag by name. Returns true if deleted, false if the tag did not exist.
167
168
169
170
171
172
173
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 167
def delete_tag(model_id:, name:)
tag = rule_version_tag_class.find_by(model_id: model_id, name: name)
return false unless tag
tag.destroy
true
end
|
#delete_version(version_id:) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 118
def delete_version(version_id:)
version = rule_version_class.find_by(id: version_id)
raise DecisionAgent::NotFoundError, "Version not found: #{version_id}" unless version
raise DecisionAgent::ValidationError, "Cannot delete active version. Please activate another version first." if version.status == "active"
version.destroy
true
rescue ActiveRecord::RecordNotFound
raise DecisionAgent::NotFoundError, "Version not found: #{version_id}"
end
|
#get_active_version(rule_id:) ⇒ Object
88
89
90
91
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 88
def get_active_version(rule_id:)
version = rule_version_class.find_by(rule_id: rule_id, status: "active")
version ? serialize_version(version) : nil
end
|
#get_tag(model_id:, name:) ⇒ Object
Retrieve a tag by name for a given model.
156
157
158
159
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 156
def get_tag(model_id:, name:)
tag = rule_version_tag_class.find_by(model_id: model_id, name: name)
tag ? serialize_tag(tag) : nil
end
|
#get_version(version_id:) ⇒ Object
75
76
77
78
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 75
def get_version(version_id:)
version = rule_version_class.find_by(id: version_id)
version ? serialize_version(version) : nil
end
|
#get_version_by_number(rule_id:, version_number:) ⇒ Object
80
81
82
83
84
85
86
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 80
def get_version_by_number(rule_id:, version_number:)
version = rule_version_class.find_by(
rule_id: rule_id,
version_number: version_number
)
version ? serialize_version(version) : nil
end
|
#list_all_versions(limit: nil) ⇒ Object
68
69
70
71
72
73
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 68
def list_all_versions(limit: nil)
query = rule_version_class.order(created_at: :desc)
query = query.limit(limit) if limit
query.map { |v| serialize_version(v) }
end
|
List all tags for a given model, sorted by name.
162
163
164
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 162
def list_tags(model_id:)
rule_version_tag_class.where(model_id: model_id).order(name: :asc).map { |t| serialize_tag(t) }
end
|
#list_versions(rule_id:, limit: nil) ⇒ Object
60
61
62
63
64
65
66
|
# File 'lib/decision_agent/versioning/activerecord_adapter.rb', line 60
def list_versions(rule_id:, limit: nil)
query = rule_version_class.where(rule_id: rule_id)
.order(version_number: :desc)
query = query.limit(limit) if limit
query.map { |v| serialize_version(v) }
end
|