active_hash 3.0.0 → 3.1.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/CHANGELOG +6 -0
- data/README.md +17 -7
- data/lib/active_hash/base.rb +1 -1
- data/lib/active_hash/relation.rb +58 -3
- data/lib/active_hash/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b300c0554a72d04ab10205af37b7f3e89dbbedca23b9c5185cc4ad0aac4e761b
|
4
|
+
data.tar.gz: 3aca6e2f970fa2362a127cafd0b88eb5df716daace9281355b5f5966981f9d1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02ab457c893ee5388d9668221b84725a1b83b1f2057a17cba98962973b3c2ab902cc9b17ad62b4fb1d4367d9fb40c13fe9d9b70caa76bdb76bf59f287f3b4b5f
|
7
|
+
data.tar.gz: d7176902700dbb797afac5ea08978b774df1428cfaab593e8895a70897cf9d9eaa39f468cc0829e0dc6aa8a687d209106e4ce6c0dd0b0df505aa3a54971f0fb8
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
2020-01-15 (v3.1.0)
|
2
|
+
- Add ActiveHash::Base.order method inspired by ActiveRecord [#177](https://github.com/zilkey/active_hash/pull/177)
|
3
|
+
- Add #to_ary to ActiveHash::Relation [#182](https://github.com/zilkey/active_hash/pull/182)
|
4
|
+
- Allow #find to behave like Enumerable#find if id is nil and a block is given [#183](https://github.com/zilkey/active_hash/pull/183)
|
5
|
+
- Delegate :sample to `records` [#189](https://github.com/zilkey/active_hash/pull/189)
|
6
|
+
|
1
7
|
2019-09-28 (v3.0.0)
|
2
8
|
- Make #where chainable [#178](https://github.com/zilkey/active_hash/pull/178)
|
3
9
|
|
data/README.md
CHANGED
@@ -131,7 +131,7 @@ NOTE: auto-defined fields will _not_ override fields you've defined, either on t
|
|
131
131
|
If some of your hash values contain nil, and you want to provide a default, you can specify defaults with the :field method:
|
132
132
|
```ruby
|
133
133
|
class Country < ActiveHash::Base
|
134
|
-
field
|
134
|
+
field :is_axis_of_evil, :default => false
|
135
135
|
end
|
136
136
|
```
|
137
137
|
## Defining Data
|
@@ -164,11 +164,13 @@ Country.find 1 # => returns the first country object with that i
|
|
164
164
|
Country.find [1,2] # => returns all Country objects with ids in the array
|
165
165
|
Country.find :all # => same as .all
|
166
166
|
Country.find :all, args # => the second argument is totally ignored, but allows it to play nicely with AR
|
167
|
+
Country.find { |country| country.name.start_with?('U') } # => returns the first country for which the block evaluates to true
|
167
168
|
Country.find_by_id 1 # => find the first object that matches the id
|
168
169
|
Country.find_by(name: 'US') # => returns the first country object with specified argument
|
169
170
|
Country.find_by!(name: 'US') # => same as find_by, but raise exception when not found
|
170
171
|
Country.where(name: 'US') # => returns all records with name: 'US'
|
171
172
|
Country.where.not(name: 'US') # => returns all records without name: 'US'
|
173
|
+
Country.order(name: :desc) # => returns all records ordered by name attribute in DESC order
|
172
174
|
```
|
173
175
|
It also gives you a few dynamic finder methods. For example, if you defined :name as a field, you'd get:
|
174
176
|
```ruby
|
@@ -206,16 +208,24 @@ Country#name= # => sets the name
|
|
206
208
|
```
|
207
209
|
## Saving in-memory records
|
208
210
|
|
209
|
-
The ActiveHash::Base.all method functions like an in-memory data store.
|
211
|
+
The ActiveHash::Base.all method functions like an in-memory data store. You can save your records as ActiveHash::Relation object by using standard ActiveRecord create and save methods:
|
210
212
|
```ruby
|
211
|
-
Country.all
|
213
|
+
Country.all
|
214
|
+
=> #<ActiveHash::Relation:0x00007f861e043bb0 @klass=Country, @all_records=[], @query_hash={}, @records_dirty=false>
|
212
215
|
Country.create
|
213
|
-
|
216
|
+
=> #<Country:0x00007f861b7abce8 @attributes={:id=>1}>
|
217
|
+
Country.all
|
218
|
+
=> #<ActiveHash::Relation:0x00007f861b7b3628 @klass=Country, @all_records=[#<Country:0x00007f861b7abce8 @attributes={:id=>1}>], @query_hash={}, @records_dirty=false>
|
214
219
|
country = Country.new
|
215
|
-
|
220
|
+
=> #<Country:0x00007f861e059938 @attributes={}>
|
221
|
+
country.new_record?
|
222
|
+
=> true
|
216
223
|
country.save
|
217
|
-
|
218
|
-
|
224
|
+
=> true
|
225
|
+
country.new_record?
|
226
|
+
# => false
|
227
|
+
Country.all
|
228
|
+
=> #<ActiveHash::Relation:0x00007f861e0ca610 @klass=Country, @all_records=[#<Country:0x00007f861b7abce8 @attributes={:id=>1}>, #<Country:0x00007f861e059938 @attributes={:id=>2}>], @query_hash={}, @records_dirty=false>
|
219
229
|
```
|
220
230
|
Notice that when adding records to the collection, it will auto-increment the id for you by default. If you use string ids, it will not auto-increment the id. Available methods are:
|
221
231
|
```
|
data/lib/active_hash/base.rb
CHANGED
@@ -188,7 +188,7 @@ module ActiveHash
|
|
188
188
|
ActiveHash::Relation.new(self, @records || [], options[:conditions] || {})
|
189
189
|
end
|
190
190
|
|
191
|
-
delegate :where, :find, :find_by, :find_by!, :find_by_id, :count, :pluck, :first, :last, to: :all
|
191
|
+
delegate :where, :find, :find_by, :find_by!, :find_by_id, :count, :pluck, :first, :last, :order, to: :all
|
192
192
|
|
193
193
|
def transaction
|
194
194
|
yield
|
data/lib/active_hash/relation.rb
CHANGED
@@ -3,8 +3,9 @@ module ActiveHash
|
|
3
3
|
include Enumerable
|
4
4
|
|
5
5
|
delegate :each, to: :records # Make Enumerable work
|
6
|
-
delegate :equal?, :==, :===, :eql?, to: :records
|
6
|
+
delegate :equal?, :==, :===, :eql?, :sort!, to: :records
|
7
7
|
delegate :empty?, :length, :first, :second, :third, :last, to: :records
|
8
|
+
delegate :sample, to: :records
|
8
9
|
|
9
10
|
def initialize(klass, all_records, query_hash = nil)
|
10
11
|
self.klass = klass
|
@@ -38,7 +39,7 @@ module ActiveHash
|
|
38
39
|
find_by(options) || (raise RecordNotFound.new("Couldn't find #{klass.name}"))
|
39
40
|
end
|
40
41
|
|
41
|
-
def find(id, *args)
|
42
|
+
def find(id = nil, *args, &block)
|
42
43
|
case id
|
43
44
|
when :all
|
44
45
|
all
|
@@ -47,7 +48,8 @@ module ActiveHash
|
|
47
48
|
when Array
|
48
49
|
id.map { |i| find(i) }
|
49
50
|
when nil
|
50
|
-
raise RecordNotFound.new("Couldn't find #{klass.name} without an ID")
|
51
|
+
raise RecordNotFound.new("Couldn't find #{klass.name} without an ID") unless block_given?
|
52
|
+
records.find(&block) # delegate to Enumerable#find if a block is given
|
51
53
|
else
|
52
54
|
find_by_id(id) || begin
|
53
55
|
raise RecordNotFound.new("Couldn't find #{klass.name} with ID=#{id}")
|
@@ -71,7 +73,25 @@ module ActiveHash
|
|
71
73
|
def reload
|
72
74
|
@records = filter_all_records_by_query_hash
|
73
75
|
end
|
76
|
+
|
77
|
+
def order(*options)
|
78
|
+
check_if_method_has_arguments!(:order, options)
|
79
|
+
relation = where({})
|
80
|
+
return relation if options.blank?
|
81
|
+
|
82
|
+
processed_args = preprocess_order_args(options)
|
83
|
+
candidates = relation.dup
|
84
|
+
|
85
|
+
order_by_args!(candidates, processed_args)
|
86
|
+
|
87
|
+
candidates
|
88
|
+
end
|
74
89
|
|
90
|
+
def to_ary
|
91
|
+
records.dup
|
92
|
+
end
|
93
|
+
|
94
|
+
|
75
95
|
attr_reader :query_hash, :klass, :all_records, :records_dirty
|
76
96
|
|
77
97
|
private
|
@@ -124,5 +144,40 @@ module ActiveHash
|
|
124
144
|
e = records.last[:id]
|
125
145
|
(range.begin..e).to_a
|
126
146
|
end
|
147
|
+
|
148
|
+
def check_if_method_has_arguments!(method_name, args)
|
149
|
+
return unless args.blank?
|
150
|
+
|
151
|
+
raise ArgumentError,
|
152
|
+
"The method .#{method_name}() must contain arguments."
|
153
|
+
end
|
154
|
+
|
155
|
+
def preprocess_order_args(order_args)
|
156
|
+
order_args.reject!(&:blank?)
|
157
|
+
return order_args.reverse! unless order_args.first.is_a?(String)
|
158
|
+
|
159
|
+
ary = order_args.first.split(', ')
|
160
|
+
ary.map! { |e| e.split(/\W+/) }.reverse!
|
161
|
+
end
|
162
|
+
|
163
|
+
def order_by_args!(candidates, args)
|
164
|
+
args.each do |arg|
|
165
|
+
field, dir = if arg.is_a?(Hash)
|
166
|
+
arg.to_a.flatten.map(&:to_sym)
|
167
|
+
elsif arg.is_a?(Array)
|
168
|
+
arg.map(&:to_sym)
|
169
|
+
else
|
170
|
+
arg.to_sym
|
171
|
+
end
|
172
|
+
|
173
|
+
candidates.sort! do |a, b|
|
174
|
+
if dir.present? && dir.to_sym.upcase.equal?(:DESC)
|
175
|
+
b[field] <=> a[field]
|
176
|
+
else
|
177
|
+
a[field] <=> b[field]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
127
182
|
end
|
128
183
|
end
|
data/lib/active_hash/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Dean
|
@@ -29,7 +29,7 @@ authors:
|
|
29
29
|
autorequire:
|
30
30
|
bindir: bin
|
31
31
|
cert_chain: []
|
32
|
-
date:
|
32
|
+
date: 2020-01-15 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: activesupport
|