ruson 1.3.0 → 1.3.1

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: 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