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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 495ecea300cebeef38e96068866a539533b308e1799937aa9efdb8786e66eaf3
4
- data.tar.gz: a149a1dc1d69ef1f416393384c7a2d8b7adbae874ca26d3f23b4c219d0df5514
3
+ metadata.gz: b300c0554a72d04ab10205af37b7f3e89dbbedca23b9c5185cc4ad0aac4e761b
4
+ data.tar.gz: 3aca6e2f970fa2362a127cafd0b88eb5df716daace9281355b5f5966981f9d1d
5
5
  SHA512:
6
- metadata.gz: 3206ab8403d58c5578fc5b4238a3834ea3fee6fe462618651d7e5377138855df959dec91df632c2882d00bd41b107ab9c46821f6724201cfc9547e0621d6d5bb
7
- data.tar.gz: ce189a601b0800ead8e4e0586b72c008272fca5c55bd7da8bac536f28804fd9cb832550bd20a186095070b4fcb5401cdbe691408087ad5b32d1a23406e189fcf
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 :is_axis_of_evil, :default => false
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. You can save your records to the the .all array by using standard ActiveRecord create and save methods:
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
- Country.all # [ <Country :id => 1> ]
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
- country.new_record? # => true
220
+ => #<Country:0x00007f861e059938 @attributes={}>
221
+ country.new_record?
222
+ => true
216
223
  country.save
217
- country.new_record? # => false
218
- Country.all # [ <Country :id => 1>, <Country :id => 2> ]
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
  ```
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module ActiveHash
2
2
  module Gem
3
- VERSION = "3.0.0"
3
+ VERSION = "3.1.0"
4
4
  end
5
5
  end
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.0.0
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: 2019-09-28 00:00:00.000000000 Z
32
+ date: 2020-01-15 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: activesupport