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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6ba358c0a8c21946a0c0c38cb4449b26cc9705c
4
- data.tar.gz: f8cad2beee638c900f6418fa06a9e2b8336acc3b
3
+ metadata.gz: 21b840689c7c1696a1d03a4e94780db8d29f6e4b
4
+ data.tar.gz: 0e55089540444e6f7d37dad011a6a52847d533c2
5
5
  SHA512:
6
- metadata.gz: 972712b50dd7ccdd03be8d5e557271e577dda9d4de3aa8dff47cab82313fbc9b2d8b74a03160f51f35d0fe0743ee59252229f35246b2d2bfb290c6abdc1aa12e
7
- data.tar.gz: b945a9e7168001e830bed9cb08bedb23812127950e5fe55e56ff18ab908db287f9679f4a1b568056afb6ec9b7f4947683753ea0f36539bb393f9fda42396363e
6
+ metadata.gz: ab14005088a2fae2c1219b18224517e141e0402bc266a4653818d20b5201feaee2930b889438603367ab666499b9a59274cb40523f8accae25b1610bbd50574c
7
+ data.tar.gz: 1e2bcbdcd38a22b70eba990ef9571659ccf26aeac6ca135e7fc53cbc6cf24fa344b991e2bdc657d8235d36c545890f0ed31c672eac69419840355530184a8148
data/Gemfile CHANGED
@@ -11,4 +11,5 @@ group :development, :test do
11
11
  gem 'pry-byebug'
12
12
  gem 'shoulda-matchers', '~> 3.1.1'
13
13
  gem 'faker'
14
+ gem 'rspec-retry'
14
15
  end
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
@@ -6,3 +6,6 @@ require 'gdatastore_mapper/version'
6
6
  require 'gdatastore_mapper/session'
7
7
  require 'gdatastore_mapper/base'
8
8
 
9
+ ActiveSupport.on_load(:i18n) do
10
+ I18n.load_path << File.dirname(__FILE__) + "/gdatastore_mapper/locale/en.yml"
11
+ end
@@ -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,5 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ required: "must exist"
5
+ taken: "has already been taken"
@@ -0,0 +1,9 @@
1
+ require 'gdatastore_mapper/validations/uniqueness_validator'
2
+
3
+ module GdatastoreMapper
4
+ module Validations
5
+ def validates_uniqueness_of(*args)
6
+ validates_with(UniquenessValidator, _merge_attributes(args))
7
+ end
8
+ end
9
+ end
@@ -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
+
@@ -1,3 +1,3 @@
1
1
  module GdatastoreMapper
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
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.6
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-22 00:00:00.000000000 Z
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