active_hash 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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