dynomite 1.1.1 → 1.2.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: bfae7abac0c8aa642ef93bde33f936415bbd4b51ee6dde84585e3cae63bef118
4
- data.tar.gz: 37160a6a7e0b36463fa4702c491ad177c10aa45c19bb474b5533d2e96c24b8e4
3
+ metadata.gz: f7ffbee55e643480271f74155ba0e255875a13c28efc7a133da1d9eb23280ac9
4
+ data.tar.gz: 6125daeb754588170f4150e90b8de7b67259b4254ce5780128321f0b83e67cce
5
5
  SHA512:
6
- metadata.gz: c228bf5f39aca9fa1efbb889bbdf6f339c8874efe7b8669f94f11291219659dc7f8ff194bb3ff6b93b3513b5f67f04d9e9aa3d7be2ae480f9837378f85e68eab
7
- data.tar.gz: e78f78984b046fb167a9f0ca6ef8b99be104b1f95648bd03863175b80517b342c4aed2cbaf1f39a5f24b286d299239de10f2e88ca786d70479e0a9899419c763
6
+ metadata.gz: 4d2f33a6a016d9e689df6b68bcdd12dc8a93a435ddc5b3d41bb821c9aa86ca548d65ac6615a071e9493a955851fa3b917ee3db7c00e8c4f9354bbf576a5c5d2f
7
+ data.tar.gz: cb7b866347a3b8dab6bc1552d1bf0d07469832d2a451c67539b8914d92229cd7ee72a430262fe2f0017f990dffe6b65005b106b210852d727149cf748b483a2b
data/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [1.2.0]
7
+ - #7 from patchkit-net/feature/validations
8
+ - Add a way to quickly define getters and setters using `column` method
9
+ - Can be used with `ActiveModel::Validations`
10
+ - Add ActiveModel::Validations (group=test,development) dependency
11
+ - Add ActiveModel::Validations Item integration spec
12
+ - Add Dynomite::Item.replace and .replace! spec with validations
13
+
6
14
  ## [1.1.1]
7
15
  - #6 from patchkit-net/feature/table-count: add Item.count
8
16
 
data/Gemfile CHANGED
@@ -4,3 +4,7 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in dynomite.gemspec
6
6
  gemspec
7
+
8
+ group :development, :test do
9
+ gem "activemodel"
10
+ end
data/README.md CHANGED
@@ -11,6 +11,8 @@ First define a class:
11
11
  ```ruby
12
12
  class Post < Dynomite::Item
13
13
  # partition_key "id" # optional, defaults to id
14
+
15
+ column :id, :title, :desc
14
16
  end
15
17
  ```
16
18
 
@@ -93,6 +95,50 @@ Post.where({category: "Drama"}, {index_name: "category-index"})
93
95
 
94
96
  Examples are also in [item_spec.rb](spec/lib/dynomite/item_spec.rb).
95
97
 
98
+ ## Column Lists
99
+
100
+ You can define your column list using the `column` method inside your item class. This gives you
101
+ a possibility to access your column fields using getters and setters. Also, any predefined column
102
+ can be passed to `ActiveModel::Validations` (see Validations).
103
+
104
+ ```ruby
105
+ class Post < Dynomite::Item
106
+ column :id, :name
107
+ end
108
+
109
+ post = Post.new
110
+ post.name = "My First Post"
111
+ post.replace
112
+
113
+ puts post.id # 1962DE7D852298C5CDC809C0FEF50D8262CEDF09
114
+ puts post.name # "My First Post"
115
+ ```
116
+
117
+ Note that any column not defined using the `column` method can still be accessed using the `attrs`
118
+ method.
119
+
120
+ ## Validations
121
+
122
+ You can add validations known from ActiveRecord to your Dynomite items.
123
+ Just add `include ActiveModel::Validations` at the top of your item class.
124
+
125
+ ```ruby
126
+ class Post < Dynomite::Item
127
+ include ActiveModel::Validations
128
+
129
+ column :id, :name # needed
130
+
131
+ validate :id, presence: true
132
+ validate :name, presence: true
133
+ end
134
+ ```
135
+
136
+ **Be sure to define all validated columns using `column` method**.
137
+
138
+ Validations are executed by default as soon as you call the `replace` method, returning `false` on
139
+ failure. It also can be ran manually using the `valid?` method just like with ActiveRecord models.
140
+
141
+
96
142
  ## Migration Support
97
143
 
98
144
  Dynomite supports ActiveRecord-like migrations. Here's a short example:
data/lib/dynomite/item.rb CHANGED
@@ -3,6 +3,8 @@ require "aws-sdk-dynamodb"
3
3
  require "digest"
4
4
  require "yaml"
5
5
 
6
+ require "dynomite/reserved_words"
7
+
6
8
  # The modeling is ActiveRecord-ish but not exactly because DynamoDB is a
7
9
  # different type of database.
8
10
  #
@@ -67,10 +69,24 @@ module Dynomite
67
69
  # The method is named replace to clearly indicate that the item is
68
70
  # fully replaced.
69
71
  def replace(hash={})
70
- attrs = self.class.replace(@attrs.deep_merge(hash))
72
+ @attrs = @attrs.deep_merge(hash)
73
+
74
+ # valid? method comes from ActiveModel::Validations
75
+ if respond_to? :valid?
76
+ return false unless valid?
77
+ end
78
+
79
+ attrs = self.class.replace(@attrs)
80
+
71
81
  @attrs = attrs # refresh attrs because it now has the id
72
82
  end
73
83
 
84
+ # Similar to replace, but raises an error on failed validation.
85
+ # Works that way only if ActiveModel::Validations are included
86
+ def replace!(hash={})
87
+ raise "Validation failed: #{errors.full_messages.join(', ')}" unless replace(hash)
88
+ end
89
+
74
90
  def find(id)
75
91
  self.class.find(id)
76
92
  end
@@ -295,5 +311,25 @@ module Dynomite
295
311
  def self.count
296
312
  table.item_count
297
313
  end
314
+
315
+ # Defines column. Defined column can be accessed by getter and setter methods of the same
316
+ # name (e.g. [model.my_column]). Attributes with undefined columns can be accessed by
317
+ # [model.attrs] method.
318
+ def self.column(*names)
319
+ names.each(&method(:add_column))
320
+ end
321
+
322
+ # @see Item.column
323
+ def self.add_column(name)
324
+ raise "'#{name}' is a reserved word" if Dynomite::RESERVED_WORDS.include?(name)
325
+
326
+ define_method(name) do
327
+ @attrs[name.to_s]
328
+ end
329
+
330
+ define_method("#{name}=") do |value|
331
+ @attrs[name.to_s] = value
332
+ end
333
+ end
298
334
  end
299
335
  end
@@ -0,0 +1,18 @@
1
+ module Dynomite
2
+ RESERVED_WORDS = %w[
3
+ as_json
4
+ attrs
5
+ attributes
6
+ delete
7
+ columns
8
+ find
9
+ getter
10
+ new_record
11
+ param_name
12
+ partition_key
13
+ replace
14
+ setter
15
+ scan
16
+ table_name
17
+ ].freeze
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Dynomite
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynomite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-10 00:00:00.000000000 Z
11
+ date: 2019-01-12 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
  - lib/dynomite/migration/generator.rb
115
115
  - lib/dynomite/migration/templates/create_table.rb
116
116
  - lib/dynomite/migration/templates/update_table.rb
117
+ - lib/dynomite/reserved_words.rb
117
118
  - lib/dynomite/version.rb
118
119
  homepage: https://github.com/tongueroo/dynomite
119
120
  licenses: []