all_futures 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/Gemfile.lock +272 -61
- data/LICENSE.txt +1 -1
- data/README.md +59 -79
- data/Rakefile +13 -1
- data/SUMMARY.md +22 -2
- data/bin/console +8 -0
- data/bin/loc +0 -0
- data/bin/setup +0 -0
- data/bin/standardize +0 -0
- data/lib/all_futures/association.rb +42 -0
- data/lib/all_futures/association_index.rb +69 -0
- data/lib/all_futures/attributes.rb +28 -0
- data/lib/all_futures/base.rb +66 -0
- data/lib/all_futures/callbacks.rb +71 -0
- data/lib/all_futures/configuration.rb +9 -0
- data/lib/all_futures/dirty.rb +116 -0
- data/lib/all_futures/embeds.rb +40 -0
- data/lib/all_futures/errors.rb +37 -0
- data/lib/all_futures/finder.rb +214 -0
- data/lib/all_futures/locale/en.yml +49 -0
- data/lib/all_futures/persistence.rb +595 -0
- data/lib/all_futures/presenter.rb +35 -0
- data/lib/all_futures/railtie.rb +26 -0
- data/lib/all_futures/translation.rb +22 -0
- data/lib/all_futures/validations.rb +10 -0
- data/lib/all_futures/version.rb +3 -1
- data/lib/all_futures/versions.rb +80 -0
- data/lib/all_futures.rb +24 -1
- data/lib/vendor/ACTIVE_ENTITY_MIT-LICENSE +42 -0
- data/lib/vendor/README.md +8 -0
- data/lib/vendor/active_entity/aggregations.rb +277 -0
- data/lib/vendor/active_entity/associations/embeds/association.rb +134 -0
- data/lib/vendor/active_entity/associations/embeds/builder/association.rb +105 -0
- data/lib/vendor/active_entity/associations/embeds/builder/collection_association.rb +71 -0
- data/lib/vendor/active_entity/associations/embeds/builder/embedded_in.rb +38 -0
- data/lib/vendor/active_entity/associations/embeds/builder/embeds_many.rb +13 -0
- data/lib/vendor/active_entity/associations/embeds/builder/embeds_one.rb +16 -0
- data/lib/vendor/active_entity/associations/embeds/builder/singular_association.rb +28 -0
- data/lib/vendor/active_entity/associations/embeds/collection_association.rb +209 -0
- data/lib/vendor/active_entity/associations/embeds/collection_proxy.rb +310 -0
- data/lib/vendor/active_entity/associations/embeds/embedded_in_association.rb +31 -0
- data/lib/vendor/active_entity/associations/embeds/embeds_many_association.rb +15 -0
- data/lib/vendor/active_entity/associations/embeds/embeds_one_association.rb +26 -0
- data/lib/vendor/active_entity/associations/embeds/singular_association.rb +35 -0
- data/lib/vendor/active_entity/associations.rb +168 -0
- data/lib/vendor/active_entity/attribute_assignment.rb +87 -0
- data/lib/vendor/active_entity/attribute_decorators.rb +90 -0
- data/lib/vendor/active_entity/attribute_methods/before_type_cast.rb +78 -0
- data/lib/vendor/active_entity/attribute_methods/dirty.rb +180 -0
- data/lib/vendor/active_entity/attribute_methods/primary_key.rb +96 -0
- data/lib/vendor/active_entity/attribute_methods/query.rb +38 -0
- data/lib/vendor/active_entity/attribute_methods/read.rb +44 -0
- data/lib/vendor/active_entity/attribute_methods/serialization.rb +90 -0
- data/lib/vendor/active_entity/attribute_methods/time_zone_conversion.rb +93 -0
- data/lib/vendor/active_entity/attribute_methods/write.rb +54 -0
- data/lib/vendor/active_entity/attribute_methods.rb +833 -0
- data/lib/vendor/active_entity/attributes.rb +240 -0
- data/lib/vendor/active_entity/base.rb +293 -0
- data/lib/vendor/active_entity/callbacks.rb +21 -0
- data/lib/vendor/active_entity/coders/json.rb +15 -0
- data/lib/vendor/active_entity/coders/yaml_column.rb +50 -0
- data/lib/vendor/active_entity/core.rb +348 -0
- data/lib/vendor/active_entity/enum.rb +260 -0
- data/lib/vendor/active_entity/errors.rb +69 -0
- data/lib/vendor/active_entity/gem_version.rb +17 -0
- data/lib/vendor/active_entity/inheritance.rb +176 -0
- data/lib/vendor/active_entity/integration.rb +78 -0
- data/lib/vendor/active_entity/locale/en.yml +45 -0
- data/lib/vendor/active_entity/model_schema.rb +118 -0
- data/lib/vendor/active_entity/nested_attributes.rb +554 -0
- data/lib/vendor/active_entity/persistence.rb +20 -0
- data/lib/vendor/active_entity/railtie.rb +76 -0
- data/lib/vendor/active_entity/readonly_attributes.rb +55 -0
- data/lib/vendor/active_entity/reflection.rb +447 -0
- data/lib/vendor/active_entity/serialization.rb +28 -0
- data/lib/vendor/active_entity/store.rb +291 -0
- data/lib/vendor/active_entity/translation.rb +24 -0
- data/lib/vendor/active_entity/type/date.rb +9 -0
- data/lib/vendor/active_entity/type/date_time.rb +9 -0
- data/lib/vendor/active_entity/type/internal/timezone.rb +17 -0
- data/lib/vendor/active_entity/type/json.rb +30 -0
- data/lib/vendor/active_entity/type/modifiers/array.rb +72 -0
- data/lib/vendor/active_entity/type/modifiers/array_without_blank.rb +19 -0
- data/lib/vendor/active_entity/type/registry.rb +112 -0
- data/lib/vendor/active_entity/type/serialized.rb +71 -0
- data/lib/vendor/active_entity/type/text.rb +11 -0
- data/lib/vendor/active_entity/type/time.rb +21 -0
- data/lib/vendor/active_entity/type/unsigned_integer.rb +17 -0
- data/lib/vendor/active_entity/type.rb +75 -0
- data/lib/vendor/active_entity/validate_embeds_association.rb +300 -0
- data/lib/vendor/active_entity/validations/absence.rb +25 -0
- data/lib/vendor/active_entity/validations/associated.rb +60 -0
- data/lib/vendor/active_entity/validations/length.rb +26 -0
- data/lib/vendor/active_entity/validations/presence.rb +68 -0
- data/lib/vendor/active_entity/validations/subset.rb +76 -0
- data/lib/vendor/active_entity/validations/uniqueness_in_embeds.rb +91 -0
- data/lib/vendor/active_entity/validations/uniqueness_on_active_record.rb +234 -0
- data/lib/vendor/active_entity/validations.rb +47 -0
- data/lib/vendor/active_entity/version.rb +10 -0
- data/lib/vendor/active_entity.rb +99 -0
- data/lib/vendor/core_ext/array_without_blank.rb +48 -0
- metadata +175 -21
- data/lib/all_futures/all_futures.rb +0 -28
- data/lib/all_futures/config.rb +0 -14
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AllFutures
|
|
4
|
+
module Finder
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
def all
|
|
9
|
+
Kredis.redis.scan_each(match: "#{name}:*").map do |key|
|
|
10
|
+
find(key.delete_prefix("#{name}:"))
|
|
11
|
+
end.sort_by(&:created_at)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def any?(&block)
|
|
15
|
+
block ? all.any?(&block) : all.any?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def count
|
|
19
|
+
Kredis.redis.keys("#{name}:*").size
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def exists?(id)
|
|
23
|
+
return all.any? unless id
|
|
24
|
+
return false if id == false
|
|
25
|
+
[Hash, Array].include?(id.class) ? where(id).any? : Kredis.redis.exists?("#{name}:#{id}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def fifth
|
|
29
|
+
find_nth 4
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def fifth!
|
|
33
|
+
fifth || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def find(*ids)
|
|
37
|
+
raise AllFutures::RecordNotFound.new("Couldn't find #{name} without an id") unless ids.flatten.present?
|
|
38
|
+
if ids.size == 1 && [String, Integer, Symbol].include?(ids.first.class)
|
|
39
|
+
record = load_model(ids.first)
|
|
40
|
+
model = new record["attributes"].merge(id: ids.first)
|
|
41
|
+
model.changes_applied # loaded values are not user-supplied changes
|
|
42
|
+
load_versions(model, record)
|
|
43
|
+
set_previous_attributes(model, record)
|
|
44
|
+
model.instance_variable_set :@created_at, Time.zone.parse(record["created_at"])
|
|
45
|
+
model.instance_variable_set :@updated_at, Time.zone.parse(record["updated_at"])
|
|
46
|
+
model
|
|
47
|
+
else
|
|
48
|
+
results = ids.flatten.map do |id|
|
|
49
|
+
find(id)
|
|
50
|
+
rescue AllFutures::RecordNotFound
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
return results if results.size == results.compact.size
|
|
54
|
+
raise AllFutures::RecordNotFound.new("Couldn't find all #{name.pluralize} with ids: #{ids.flatten.join(", ")} (found #{results.compact.size} results, but was looking for #{results.size})")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def find_by(attrs = {})
|
|
59
|
+
result = where(attrs)
|
|
60
|
+
result.any? ? result.first : nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def find_by!(attrs = {})
|
|
64
|
+
result = find_by(attrs)
|
|
65
|
+
result.present? ? result : raise(AllFutures::RecordNotFound.new("Couldn't find #{name} with #{_pretty_attrs(attrs)}"))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def find_or_create_by(attrs = {}, &block)
|
|
69
|
+
return create({}, &block) unless attrs.present?
|
|
70
|
+
find_by!(attrs)
|
|
71
|
+
rescue AllFutures::RecordNotFound
|
|
72
|
+
create(attrs, &block)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def find_or_initialize_by(attrs = {}, &block)
|
|
76
|
+
return new({}, &block) unless attrs.present?
|
|
77
|
+
find_by!(attrs)
|
|
78
|
+
rescue AllFutures::RecordNotFound
|
|
79
|
+
new(attrs, &block)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def find_sole_by(attrs = {}, &block)
|
|
83
|
+
found, undesired = where(attrs, &block).first(2)
|
|
84
|
+
|
|
85
|
+
if found.nil?
|
|
86
|
+
raise AllFutures::RecordNotFound.new("Couldn't find #{name} record")
|
|
87
|
+
elsif undesired.present?
|
|
88
|
+
raise AllFutures::SoleRecordExceeded.new("Found multiple #{name} records when expecting only one")
|
|
89
|
+
else
|
|
90
|
+
found
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def first(limit = nil)
|
|
95
|
+
limit ? all.first(limit) : all.first
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def first!
|
|
99
|
+
first || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def forty_two
|
|
103
|
+
find_nth 41
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def forty_two!
|
|
107
|
+
forty_two || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def fourth
|
|
111
|
+
find_nth 3
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def fourth!
|
|
115
|
+
fourth || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def ids
|
|
119
|
+
Kredis.redis.keys("#{name}:*").map { |id| id.delete_prefix("#{name}:") }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def include?(record)
|
|
123
|
+
record.is_a?(self) && exists?(record.id)
|
|
124
|
+
end
|
|
125
|
+
alias_method :member?, :include?
|
|
126
|
+
|
|
127
|
+
def last(limit = nil)
|
|
128
|
+
limit ? all.last(limit) : all.last
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def last!
|
|
132
|
+
last || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def second
|
|
136
|
+
find_nth 1
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def second!
|
|
140
|
+
second || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def second_to_last
|
|
144
|
+
find_nth_from_last 1
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def second_to_last!
|
|
148
|
+
second_to_last || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def sole
|
|
152
|
+
found, undesired = first(2)
|
|
153
|
+
|
|
154
|
+
if found.nil?
|
|
155
|
+
raise AllFutures::RecordNotFound.new("Couldn't find #{name} record")
|
|
156
|
+
elsif undesired.present?
|
|
157
|
+
raise AllFutures::SoleRecordExceeded.new("Found multiple #{name} records when expecting only one")
|
|
158
|
+
else
|
|
159
|
+
found
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def third
|
|
164
|
+
find_nth 2
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def third!
|
|
168
|
+
third || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def third_to_last
|
|
172
|
+
find_nth_from_last 2
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def third_to_last!
|
|
176
|
+
third_to_last || raise(AllFutures::RecordNotFound.new("Couldn't find #{name} record"))
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def where(attrs = {}, &block)
|
|
180
|
+
if block.blank?
|
|
181
|
+
return all if attrs.blank?
|
|
182
|
+
begin
|
|
183
|
+
return [find(attrs.values.first)] if attrs.one? && attrs.keys.first == :id
|
|
184
|
+
rescue AllFutures::RecordNotFound
|
|
185
|
+
return []
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
attrs.each_key { |key| raise AllFutures::InvalidAttribute.new("#{key} is not a valid attribute") unless valid_attribute?(key) }
|
|
190
|
+
all.select do |record|
|
|
191
|
+
attrs.all? do |(attribute, value)|
|
|
192
|
+
record.send(attribute) == value.to_s
|
|
193
|
+
end && (block ? block.call(record) : true)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
private
|
|
198
|
+
|
|
199
|
+
def find_nth(index)
|
|
200
|
+
records = all
|
|
201
|
+
(records.size >= index) ? records[index] : nil
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def find_nth_from_last(index)
|
|
205
|
+
records = all.reverse
|
|
206
|
+
(records.size >= index) ? records[index] : nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def _pretty_attrs(attrs)
|
|
210
|
+
attrs.map { |key, value| "#{key}: #{value}" }.join(", ")
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
en:
|
|
2
|
+
# Shamelessly stolen/borrowed from ActiveEntity! Thank you, Jun!
|
|
3
|
+
# Attributes names common to most models
|
|
4
|
+
#attributes:
|
|
5
|
+
#created_at: "Created at"
|
|
6
|
+
#updated_at: "Updated at"
|
|
7
|
+
|
|
8
|
+
# Default error messages
|
|
9
|
+
errors:
|
|
10
|
+
messages:
|
|
11
|
+
non_subset: "is not subset of the given list"
|
|
12
|
+
duplicated: "duplicated"
|
|
13
|
+
|
|
14
|
+
# AllFutures models configuration
|
|
15
|
+
allfutures:
|
|
16
|
+
errors:
|
|
17
|
+
messages:
|
|
18
|
+
record_invalid: "Validation failed: %{errors}"
|
|
19
|
+
restrict_dependent_destroy:
|
|
20
|
+
embeds_one: "Cannot delete record because a dependent %{record} exists"
|
|
21
|
+
embeds_many: "Cannot delete record because dependent %{record} exist"
|
|
22
|
+
# Append your own errors here or at the model/attributes scope.
|
|
23
|
+
|
|
24
|
+
# You can define own errors for models or model attributes.
|
|
25
|
+
# The values :model, :attribute and :value are always available for interpolation.
|
|
26
|
+
#
|
|
27
|
+
# For example,
|
|
28
|
+
# models:
|
|
29
|
+
# user:
|
|
30
|
+
# blank: "This is a custom blank message for %{model}: %{attribute}"
|
|
31
|
+
# attributes:
|
|
32
|
+
# login:
|
|
33
|
+
# blank: "This is a custom blank message for User login"
|
|
34
|
+
# Will define custom blank validation message for User model and
|
|
35
|
+
# custom blank validation message for login attribute of User model.
|
|
36
|
+
#models:
|
|
37
|
+
|
|
38
|
+
# Translate model names. Used in Model.human_name().
|
|
39
|
+
#models:
|
|
40
|
+
# For example,
|
|
41
|
+
# user: "Dude"
|
|
42
|
+
# will translate User model name to "Dude"
|
|
43
|
+
|
|
44
|
+
# Translate model attribute names. Used in Model.human_attribute_name(attribute).
|
|
45
|
+
#attributes:
|
|
46
|
+
# For example,
|
|
47
|
+
# user:
|
|
48
|
+
# login: "Handle"
|
|
49
|
+
# will translate User attribute "login" as "Handle"
|