protobuf-activerecord 2.1.0.beta → 2.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,8 +16,15 @@ module Protoable
16
16
  #
17
17
  # Optionally, a parser can be provided that will be called, passing the
18
18
  # field value as an argument. This allows custom data parsers to be used
19
- # so that they don't have to be handled by scopes. Parsers must respond
20
- # to `call` and accept a single parameter.
19
+ # so that they don't have to be handled by scopes. Parsers can be procs,
20
+ # lambdas, or symbolized method names and must accept the value of the
21
+ # field as a parameter.
22
+ #
23
+ # > **Deprecated usage**: Previous versions required the scope to be passed
24
+ # as a second argument. This has been replaced with the new hash-style
25
+ # options or simply relying on the defaults. While it will still work
26
+ # until v3.0 is released, it has been deprecated.
27
+ #
21
28
  #
22
29
  # Examples:
23
30
  #
@@ -29,24 +36,43 @@ module Protoable
29
36
  # field_scope :guid
30
37
  #
31
38
  # # With a custom scope
32
- # field_scope :guid, :custom_guid_scope
39
+ # field_scope :guid, :scope => :custom_guid_scope
33
40
  #
34
41
  # # With a custom parser that converts the value to an integer
35
- # field_scope :guid, :by_guid, lambda { |value| value.to_i }
42
+ # field_scope :guid, :scope => :custom_guid_scope, :parser => lambda { |value| value.to_i }
36
43
  # end
37
44
  #
38
- def field_scope(field, scope_name = nil, parser = nil)
39
- scope_name ||= :"by_#{field}"
45
+ def field_scope(field, *args)
46
+ # TODO: For backwards compatibility. Remove this in the next major release.
47
+ options = args.extract_options!
48
+
49
+ scope_name = case
50
+ when args.present? then
51
+ args.first
52
+ when options.include?(:scope) then
53
+ options[:scope]
54
+ else
55
+ # When no scope is defined, assume the scope is the field, prefixed with `by_`
56
+ :"by_#{field}"
57
+ end
40
58
  searchable_fields[field] = scope_name
41
59
 
42
- # When no parser is defined, define one that simply returns the value
43
- searchable_field_parsers[field] = parser || proc { |value| value }
60
+ searchable_field_parsers[field] = options[:parser] if options[:parser]
44
61
  end
45
62
 
46
63
  # :noapi:
47
64
  def parse_search_values(proto, field)
48
65
  value = proto.__send__(field)
49
- value = searchable_field_parsers[field].call(value)
66
+
67
+ if searchable_field_parsers[field]
68
+ parser = searchable_field_parsers[field]
69
+
70
+ if parser.respond_to?(:to_sym)
71
+ value = self.__send__(parser.to_sym, value)
72
+ else
73
+ value = parser.call(value)
74
+ end
75
+ end
50
76
 
51
77
  values = [ value ].flatten
52
78
  values.map!(&:to_i) if proto.get_field_by_name(field).enum?
@@ -0,0 +1,39 @@
1
+ module Protoable
2
+ module Validations
3
+ extend ::ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ # Validates whether the value of the specified attribute is available in
7
+ # the given Protobuf Enum. The enumeration should be passed as a class
8
+ # that defines the enumeration:
9
+ #
10
+ # ```
11
+ # class User < ActiveRecord::Base
12
+ # include ::Protoable
13
+ #
14
+ # validates_enumeration_of :role_type, :with => RoleType, :allow_nil => true
15
+ # end
16
+ # ```
17
+ #
18
+ # In this example, RoleType is a defined as a protobuf enum.
19
+ #
20
+ # It accepts the same options as `validates_inclusion_of` (the :in option
21
+ # is automatically set and will be overwritten).
22
+ #
23
+ def validates_enumeration_of(*args)
24
+ options = args.extract_options!
25
+ enumerable = options.delete(:with)
26
+
27
+ raise ArgumentError, ":with must be specified" if enumerable.nil?
28
+
29
+ if enumerable < ::Protobuf::Enum
30
+ options[:in] = enumerable.values.values.map(&:value)
31
+ end
32
+
33
+ args << options
34
+
35
+ validates_inclusion_of(*args)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,6 +4,7 @@ require 'protobuf/activerecord/protoable/persistence'
4
4
  require 'protobuf/activerecord/protoable/scope'
5
5
  require 'protobuf/activerecord/protoable/serialization'
6
6
  require 'protobuf/activerecord/protoable/transformation'
7
+ require 'protobuf/activerecord/protoable/validations'
7
8
 
8
9
  module Protoable
9
10
  def self.included(klass)
@@ -13,5 +14,6 @@ module Protoable
13
14
  klass.__send__(:include, Protoable::Persistence)
14
15
  klass.__send__(:include, Protoable::Serialization)
15
16
  klass.__send__(:include, Protoable::Transformation)
17
+ klass.__send__(:include, Protoable::Validations)
16
18
  end
17
19
  end
@@ -1,5 +1,5 @@
1
1
  module Protobuf
2
2
  module ActiveRecord
3
- VERSION = "2.1.0.beta"
3
+ VERSION = "2.1.0.beta2"
4
4
  end
5
5
  end
@@ -40,9 +40,60 @@ describe Protoable::Scope do
40
40
  before { @fields = User.instance_variable_get("@_searchable_fields") }
41
41
  after { User.instance_variable_set("@_searchable_fields", @fields) }
42
42
 
43
- it "stores the search scope in the searchable fields hash using the field as the key" do
44
- User.field_scope :guid, :by_guid
45
- User.searchable_fields[:guid].should eq :by_guid
43
+ context "when scope is passed in the old style" do
44
+ it "defines the given field as searchable using the given scope" do
45
+ User.field_scope :guid, :by_guid
46
+ User.searchable_fields[:guid].should eq :by_guid
47
+ end
48
+ end
49
+
50
+ context "when :scope is not defined" do
51
+ it "defines the given field as searchable using the `by_[:field]` as the scope" do
52
+ User.field_scope :guid
53
+ User.searchable_fields[:guid].should eq :by_guid
54
+ end
55
+ end
56
+
57
+ context "when :scope is defined" do
58
+ it "defines the given field as searchable using the given :scope" do
59
+ User.field_scope :guid, :scope => :custom_scope
60
+ User.searchable_fields[:guid].should eq :custom_scope
61
+ end
62
+ end
63
+
64
+ context "when :parser is not defined" do
65
+ it "doesn't define the given field as parseable" do
66
+ User.field_scope :guid
67
+ User.searchable_field_parsers[:guid].should eq nil
68
+ end
69
+ end
70
+
71
+ context "when :parser is defined" do
72
+ before { @field_parsers = User.instance_variable_get("@_searchable_field_parsers") }
73
+ after { User.instance_variable_set("@_searchable_field_parsers", @field_parsers) }
74
+
75
+ it "defines the given field as parseable using the given :parser" do
76
+ User.field_scope :guid, :parser => :parser
77
+ User.searchable_field_parsers[:guid].should eq :parser
78
+ end
79
+ end
80
+ end
81
+
82
+ describe ".parse_search_values" do
83
+ it "converts single values to collections"
84
+
85
+ context "when a field parser is defined" do
86
+ context "and the parser responds to :to_sym" do
87
+ it "calls `send`, passing it the parser and value"
88
+ end
89
+
90
+ context "and the parser does not respond to :to_sym" do
91
+ it "calls the parser, passing it the value"
92
+ end
93
+ end
94
+
95
+ context "when the field is an enum" do
96
+ it "maps values to integers"
46
97
  end
47
98
  end
48
99
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protobuf-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.beta
4
+ version: 2.1.0.beta2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-21 00:00:00.000000000 Z
12
+ date: 2013-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -209,6 +209,7 @@ files:
209
209
  - lib/protobuf/activerecord/protoable/scope.rb
210
210
  - lib/protobuf/activerecord/protoable/serialization.rb
211
211
  - lib/protobuf/activerecord/protoable/transformation.rb
212
+ - lib/protobuf/activerecord/protoable/validations.rb
212
213
  - lib/protobuf/activerecord/protobuf_ext/message.rb
213
214
  - lib/protobuf/activerecord/version.rb
214
215
  - protobuf-activerecord.gemspec
@@ -239,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
239
240
  version: '0'
240
241
  segments:
241
242
  - 0
242
- hash: 2337364999688507357
243
+ hash: 1690905845490164908
243
244
  required_rubygems_version: !ruby/object:Gem::Requirement
244
245
  none: false
245
246
  requirements: