ruson 1.3.0 → 1.3.1

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: d3b5eacde447ed93d7ecffd81ba095d20dad1398687f5138dd7f2267bfd5bacf
4
- data.tar.gz: 172098d6792639c7c785eba55332b323785c879ce59458766d60787458b043bc
3
+ metadata.gz: ca2fa65cff2663ee3a6081d16d29f707ac59a972024488ca8036d500d071c5aa
4
+ data.tar.gz: 5c5286b425b029c7e667f7909f32b60b0eac76d46cc028692a386e8378db4d7c
5
5
  SHA512:
6
- metadata.gz: 1e33b1b04e784cc26494d08fb02a26c9afa9f42bd3595c6f4527da6f59ce937c8df8b4d4b8d95bf528d6ecdbc9384cddc80de738b59d5224098fd9c4c45da3da
7
- data.tar.gz: 5cb1a2daa61f905266afb804878a59a0f617e19d530649651c2fbd978c9854c87c243d1002c7baa4e11bc95b6590e75207f4a2af5942941444d378693cbec1f2
6
+ metadata.gz: b9066c6c2df513dbed5d260d1c15b880c1bd707241d195211c583bf4cab245c4dcaef76c0f1cec72dfb50da8359a71edabcf9fbcf608c6bcf3909119672e26e6
7
+ data.tar.gz: c5b71fa2d7385b882f57a52b2124c99b004d82c45fd464d61bce1fe574d26cfd517e65c61195956de4694f36da14001148ac66aad307f9d42d487923d3bb02bd
data/README.md CHANGED
@@ -123,34 +123,42 @@ post.picture.url #=> 'http://sample.com/picture.png'
123
123
 
124
124
  ###### Primary classes
125
125
 
126
+ * Array
126
127
  * Boolean
127
- * Integer
128
128
  * Float
129
+ * Integer
130
+ * Time
129
131
 
130
132
 
131
133
  post.json
132
134
  ```json
133
135
  {
134
136
  "title": "Ruson",
137
+ "items": ["orange", "apple"],
135
138
  "is_new": "true",
139
+ "rate": "3.8",
136
140
  "view": "1234",
137
- "rate": "3.8"
141
+ "expired_at": 1575608299
138
142
  }
139
143
  ```
140
144
 
141
145
  ```ruby
142
146
  class Post < Ruson::Base
143
147
  field :title
148
+ field :items, class: Array
144
149
  field :is_new, class: Boolean
145
- field :view, class: Integer
146
150
  field :rate, class: Float
151
+ field :view, class: Integer
152
+ field :expired_at, class: Time
147
153
  end
148
154
 
149
155
  json = File.read('post.json')
150
156
  post = Post.new(json)
157
+ post.items #=> ["orange", "apple"]
151
158
  post.is_new #=> true
152
- post.view #=> 1234
153
159
  post.rate #=> 3.8
160
+ post.view #=> 1234
161
+ post.expired_at #=> 2019-12-06 04:58:19 +0000
154
162
  ```
155
163
 
156
164
  ##### each class
@@ -337,7 +345,21 @@ Ruson.output_folder = './db/'
337
345
  #### Find a record by ID
338
346
 
339
347
  ```ruby
340
- user = User.find(1) # Searches for a ./db/Users/1.json file
348
+ User.find(1) # Searches for a ./db/Users/1.json file
349
+
350
+ # Searching a user which doesn't exist
351
+ User.find(1234) #=> nil
352
+ User.find!(1234) #=> raises Ruson::RecordNotFound
353
+ ```
354
+
355
+ #### Find first record
356
+
357
+ ```ruby
358
+ User.first # Loads the first ./db/Users/*.json file.
359
+
360
+ # Without existing User records
361
+ User.first #=> nil
362
+ User.first! #=> raises Ruson::RecordNotFound
341
363
  ```
342
364
 
343
365
  ## Development
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'active_support'
3
3
  require 'active_support/core_ext'
4
4
 
5
+ require 'ruson/class/array'
5
6
  require 'ruson/class/boolean'
6
7
  require 'ruson/class/float'
7
8
  require 'ruson/class/integer'
@@ -58,6 +59,7 @@ module Ruson
58
59
  end
59
60
  end
60
61
 
62
+ # ~~~~ Mixins ~~~~
61
63
  include Ruson::Converter
62
64
  include Ruson::Json
63
65
  include Ruson::Nilable
@@ -65,6 +67,15 @@ module Ruson
65
67
  include Ruson::Querying
66
68
  include Ruson::Value
67
69
 
70
+ # ~~~~ Class Methods ~~~~
71
+ def self.ensure_output_folder_is_defined
72
+ return if Ruson.output_folder
73
+
74
+ raise ArgumentError, 'No output folder defined. You can define it ' \
75
+ 'using Ruson.output_folder = "/path/to/db/folder"'
76
+ end
77
+
78
+ # ~~~~ Instance Methods ~~~~
68
79
  def initialize(json, root_key: nil)
69
80
  params = get_hash_from_json(json)
70
81
  params = params[root_key.to_s] unless root_key.nil?
@@ -77,8 +88,9 @@ module Ruson
77
88
 
78
89
  res.inject({}) do |result, attributes|
79
90
  key, value = attributes
80
- if self.class.accessors[key] && self.class.accessors[key].key?(:name)
81
- result[self.class.accessors[key][:name].to_s] = value
91
+ accessor = self.class.accessors[key]
92
+ if accessor && accessor&.key?(:name)
93
+ result[accessor[:name]] = value
82
94
  else
83
95
  result[key] = value
84
96
  end
@@ -86,30 +98,38 @@ module Ruson
86
98
  end
87
99
  end
88
100
 
89
- def to_json
90
- to_hash.to_json
101
+ def to_json(options = {})
102
+ hash = to_hash
103
+
104
+ options[:exclude].each { |key| hash.delete(key) } if options[:exclude]
105
+
106
+ hash.to_json
91
107
  end
92
108
 
93
109
  private
94
110
 
111
+ def cast_value(value, accessor_options, options = {})
112
+ check_nilable(value, accessor_options)
113
+ get_val(value, accessor_options)
114
+ end
115
+
95
116
  def init_attributes(accessors, params)
96
117
  update_attributes(accessors, params)
97
118
 
98
119
  self.class.attr_accessor(:id)
99
- set_attribute(:id, params[:id]) if params[:id]
120
+ set_attribute(:id, params[:id]) if params && params[:id]
100
121
  end
101
122
 
102
- def set_attribute(attr_name, val)
103
- self.send("#{attr_name}=".to_sym, val)
123
+ def set_attribute(attr_name, value)
124
+ send("#{attr_name}=".to_sym, value)
104
125
  end
105
126
 
106
127
  def update_attributes(accessors, params)
107
128
  accessors.each do |key, options|
108
- value = params[options[:name]] || params[key]
129
+ value = params[options[:name]] || params[key] if params
109
130
 
110
- check_nilable(value, options)
111
- val = get_val(value, options)
112
- set_attribute(key, val)
131
+ casted_value = cast_value(value, options)
132
+ set_attribute(key, casted_value)
113
133
  end
114
134
  end
115
135
  end
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def self.new(value)
3
+ Array(value)
4
+ end
5
+ end
@@ -1,7 +1,9 @@
1
1
  module Ruson
2
2
  module Json
3
3
  def get_hash_from_json(json)
4
+ return unless json
4
5
  return json if json.class == ActiveSupport::HashWithIndifferentAccess
6
+
5
7
  (json.class == Hash ? json : JSON.parse(json)).with_indifferent_access
6
8
  end
7
9
  end
@@ -25,13 +25,6 @@ module Ruson
25
25
  true
26
26
  end
27
27
 
28
- def ensure_output_folder_is_defined
29
- return if Ruson.output_folder
30
-
31
- raise ArgumentError, 'No output folder defined. You can define it ' \
32
- 'using Ruson.output_folder = "/path/to/db/folder"'
33
- end
34
-
35
28
  def ensure_model_folder_exists
36
29
  return if File.exist?(self.class.model_base_path)
37
30
 
@@ -60,12 +53,12 @@ module Ruson
60
53
 
61
54
  def write_file_to_disk
62
55
  File.open(model_path, 'w') do |file|
63
- file.write(to_json)
56
+ file.write(to_json(exclude: %i[id]))
64
57
  end
65
58
  end
66
59
 
67
60
  def save
68
- ensure_output_folder_is_defined
61
+ self.class.ensure_output_folder_is_defined
69
62
  generate_uniq_id
70
63
  write_file_to_disk
71
64
  true
@@ -6,14 +6,13 @@ module Ruson
6
6
 
7
7
  module ClassMethods
8
8
  def find(id)
9
+ ensure_output_folder_is_defined
10
+
9
11
  file_path = File.join(model_base_path, "#{id}.json")
10
12
 
11
13
  return unless File.exist?(file_path)
12
14
 
13
- json = JSON.parse(File.read(file_path))
14
- json[:id] = id
15
-
16
- new json
15
+ load(file_path, id: id)
17
16
  end
18
17
 
19
18
  def find!(id)
@@ -23,6 +22,34 @@ module Ruson
23
22
 
24
23
  record
25
24
  end
25
+
26
+ def first
27
+ ensure_output_folder_is_defined
28
+
29
+ file_path = Dir.glob(File.join(model_base_path, '*.json')).first
30
+
31
+ return unless file_path
32
+
33
+ id = File.basename(file_path, '.json').to_i
34
+
35
+ load(file_path, id: id)
36
+ end
37
+
38
+ def first!
39
+ record = first
40
+
41
+ raise Ruson::RecordNotFound unless record
42
+
43
+ record
44
+ end
45
+
46
+ def load(file_path, extra_json = {})
47
+ json = JSON.parse(File.read(file_path))
48
+
49
+ json.merge!(extra_json) if extra_json
50
+
51
+ new json
52
+ end
26
53
  end
27
54
  end
28
55
  end
@@ -13,7 +13,6 @@ module Ruson
13
13
  private
14
14
 
15
15
  def class_param(param, klass)
16
- return nil if param.nil?
17
16
  klass.new(param)
18
17
  end
19
18
 
@@ -1,3 +1,3 @@
1
1
  module Ruson
2
- VERSION = '1.3.0'
2
+ VERSION = '1.3.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruson
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - klriutsa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-03 00:00:00.000000000 Z
11
+ date: 2019-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -114,6 +114,7 @@ files:
114
114
  - bin/setup
115
115
  - lib/ruson.rb
116
116
  - lib/ruson/base.rb
117
+ - lib/ruson/class/array.rb
117
118
  - lib/ruson/class/boolean.rb
118
119
  - lib/ruson/class/float.rb
119
120
  - lib/ruson/class/integer.rb