gdatastore_mapper 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +16 -0
- data/lib/gdatastore_mapper.rb +3 -0
- data/lib/gdatastore_mapper/base.rb +2 -0
- data/lib/gdatastore_mapper/locale/en.yml +5 -0
- data/lib/gdatastore_mapper/validations.rb +9 -0
- data/lib/gdatastore_mapper/validations/uniqueness_validator.rb +87 -0
- data/lib/gdatastore_mapper/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21b840689c7c1696a1d03a4e94780db8d29f6e4b
|
4
|
+
data.tar.gz: 0e55089540444e6f7d37dad011a6a52847d533c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab14005088a2fae2c1219b18224517e141e0402bc266a4653818d20b5201feaee2930b889438603367ab666499b9a59274cb40523f8accae25b1610bbd50574c
|
7
|
+
data.tar.gz: 1e2bcbdcd38a22b70eba990ef9571659ccf26aeac6ca135e7fc53cbc6cf24fa344b991e2bdc657d8235d36c545890f0ed31c672eac69419840355530184a8148
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Once you install GdatastoreMapper you can use Google Cloud Datastore like Active
|
|
16
16
|
- [Associations](#associations)
|
17
17
|
- [One to Many](#one-to-many)
|
18
18
|
- [Callbacks](#callbacks)
|
19
|
+
- [Validations](#validations)
|
19
20
|
- [Contact](#contact)
|
20
21
|
- [Development](#development)
|
21
22
|
|
@@ -228,6 +229,21 @@ class Book
|
|
228
229
|
end
|
229
230
|
```
|
230
231
|
|
232
|
+
## Validations
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
class Author
|
236
|
+
include GdatastoreMapper::Base
|
237
|
+
|
238
|
+
attr_accessor :email
|
239
|
+
|
240
|
+
validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
|
241
|
+
validates :email, length: { in: 3..20 }
|
242
|
+
validates_uniqueness_of :email
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
|
231
247
|
## Contact
|
232
248
|
|
233
249
|
Please shoot me an e-mail if you find any issues, ideas and comments. shinya.kitamura.14@gmail.com
|
data/lib/gdatastore_mapper.rb
CHANGED
@@ -3,6 +3,7 @@ require 'gdatastore_mapper/scoping'
|
|
3
3
|
require 'gdatastore_mapper/associations'
|
4
4
|
require 'gdatastore_mapper/persistence'
|
5
5
|
require 'gdatastore_mapper/persistence/class_methods'
|
6
|
+
require 'gdatastore_mapper/validations'
|
6
7
|
|
7
8
|
module GdatastoreMapper
|
8
9
|
module Base
|
@@ -20,6 +21,7 @@ module GdatastoreMapper
|
|
20
21
|
extend Associations
|
21
22
|
include Persistence
|
22
23
|
extend Persistence::ClassMethods
|
24
|
+
extend Validations
|
23
25
|
end
|
24
26
|
|
25
27
|
module ClassMethods
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module GdatastoreMapper
|
2
|
+
module Validations
|
3
|
+
class UniquenessValidator < ActiveModel::EachValidator # :nodoc:
|
4
|
+
def initialize(options)
|
5
|
+
if options[:conditions] && !options[:conditions].respond_to?(:call)
|
6
|
+
raise ArgumentError, "#{options[:conditions]} was passed as :conditions but is not callable. " \
|
7
|
+
"Pass a callable instead: `conditions: -> { where(approved: true) }`"
|
8
|
+
end
|
9
|
+
super({ case_sensitive: true }.merge!(options))
|
10
|
+
@klass = options[:class]
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_each(record, attribute, value)
|
14
|
+
finder_class = find_finder_class_for(record).first
|
15
|
+
# value = map_enum_attribute(finder_class, attribute, value)
|
16
|
+
|
17
|
+
relation = build_relation(finder_class, attribute, value)
|
18
|
+
if record.persisted?
|
19
|
+
relation = detect_relation(relation, record.id)
|
20
|
+
# if finder_class.primary_key
|
21
|
+
# relation = relation.where.not(finder_class.primary_key => record.id_in_database || record.id)
|
22
|
+
# else
|
23
|
+
# raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
24
|
+
# end
|
25
|
+
end
|
26
|
+
relation = scope_relation(record, relation)
|
27
|
+
relation = relation.merge(options[:conditions]) if options[:conditions]
|
28
|
+
|
29
|
+
if relation.present?
|
30
|
+
error_options = options.except(:case_sensitive, :scope, :conditions)
|
31
|
+
error_options[:value] = value
|
32
|
+
|
33
|
+
record.errors.add(attribute, :taken, error_options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def find_finder_class_for(record)
|
39
|
+
class_hierarchy = [record.class]
|
40
|
+
|
41
|
+
while class_hierarchy.first != @klass
|
42
|
+
class_hierarchy.unshift(class_hierarchy.first.superclass)
|
43
|
+
end
|
44
|
+
|
45
|
+
# class_hierarchy.detect { |klass| !klass.abstract_class? }
|
46
|
+
class_hierarchy
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_relation(klass, attribute, value)
|
50
|
+
# klass.unscoped.where!({ attribute => value }, options)
|
51
|
+
klass.where({ attribute => value })
|
52
|
+
end
|
53
|
+
|
54
|
+
def scope_relation(record, relation)
|
55
|
+
Array(options[:scope]).each do |scope_item|
|
56
|
+
scope_value = if record.class._reflect_on_association(scope_item)
|
57
|
+
record.association(scope_item).reader
|
58
|
+
else
|
59
|
+
record._read_attribute(scope_item)
|
60
|
+
end
|
61
|
+
relation = relation.where(scope_item => scope_value)
|
62
|
+
end
|
63
|
+
|
64
|
+
relation
|
65
|
+
end
|
66
|
+
|
67
|
+
def map_enum_attribute(klass, attribute, value)
|
68
|
+
mapping = klass.defined_enums[attribute.to_s]
|
69
|
+
value = mapping[value] if value && mapping
|
70
|
+
value
|
71
|
+
end
|
72
|
+
|
73
|
+
def detect_relation(records, id)
|
74
|
+
records.select do |record|
|
75
|
+
record.id != id
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module ClassMethods
|
81
|
+
def validates_uniqueness_of(*attr_names)
|
82
|
+
validates_with UniquenessValidator, _merge_attributes(attr_names)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdatastore_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shinya Kitamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-datastore
|
@@ -116,11 +116,14 @@ files:
|
|
116
116
|
- lib/gdatastore_mapper/associations.rb
|
117
117
|
- lib/gdatastore_mapper/associations/has_many.rb
|
118
118
|
- lib/gdatastore_mapper/base.rb
|
119
|
+
- lib/gdatastore_mapper/locale/en.yml
|
119
120
|
- lib/gdatastore_mapper/persistence.rb
|
120
121
|
- lib/gdatastore_mapper/persistence/class_methods.rb
|
121
122
|
- lib/gdatastore_mapper/relation.rb
|
122
123
|
- lib/gdatastore_mapper/scoping.rb
|
123
124
|
- lib/gdatastore_mapper/session.rb
|
125
|
+
- lib/gdatastore_mapper/validations.rb
|
126
|
+
- lib/gdatastore_mapper/validations/uniqueness_validator.rb
|
124
127
|
- lib/gdatastore_mapper/version.rb
|
125
128
|
- rails_example/.gitignore
|
126
129
|
- rails_example/Gemfile
|