paraphrase 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
1
  Gemfile.lock
2
2
  doc/
3
- pkg/
3
+ *.gem
4
4
  vendor/cache/*.gem
5
5
  .yardoc
data/CHANGELOG ADDED
@@ -0,0 +1,11 @@
1
+ 0.3.0 / 7-5-2012
2
+
3
+ * Allow nil values to be passed to scoped using :allow_nil option.
4
+ * Require/whitelist individual keys of a compound key.
5
+ * Update Paraphrase::Syntax.register_mapping to update an existing mapping to
6
+ avoid errors when a model class is reloaded during development.
7
+
8
+ 0.2.0 / 6-22-2012
9
+
10
+ * Initial release
11
+
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/edd_d/src/paraphrase
3
3
  specs:
4
- paraphrase (0.1.0)
4
+ paraphrase (0.3.0)
5
5
  activemodel (~> 3.0)
6
6
  activerecord (~> 3.0)
7
7
  activesupport (~> 3.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/edd_d/src/paraphrase
3
3
  specs:
4
- paraphrase (0.1.0)
4
+ paraphrase (0.3.0)
5
5
  activemodel (~> 3.0)
6
6
  activerecord (~> 3.0)
7
7
  activesupport (~> 3.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/edd_d/src/paraphrase
3
3
  specs:
4
- paraphrase (0.1.0)
4
+ paraphrase (0.3.0)
5
5
  activemodel (~> 3.0)
6
6
  activerecord (~> 3.0)
7
7
  activesupport (~> 3.0)
@@ -2,7 +2,6 @@ require 'active_support/core_ext/class/attribute_accessors'
2
2
  require 'active_support/core_ext/class/attribute'
3
3
  require 'active_support/core_ext/module/delegation'
4
4
  require 'active_model/naming'
5
- require 'active_model/errors'
6
5
 
7
6
  module Paraphrase
8
7
  class Query
@@ -8,7 +8,13 @@ module Paraphrase
8
8
  #
9
9
  # @!attribute [r] options
10
10
  # @return [Hash] configuration options
11
- attr_reader :param_keys, :method_name, :options
11
+ #
12
+ # @!attribute [r] required_keys
13
+ # @return [Array] keys required for query
14
+ #
15
+ # @!attribute [r] whitelisted_keys
16
+ # @return [Array] keys allowed to be nil
17
+ attr_reader :param_keys, :method_name, :options, :required_keys, :whitelisted_keys
12
18
 
13
19
 
14
20
  # @param [Symbol] name name of the scope
@@ -17,15 +23,30 @@ module Paraphrase
17
23
  # @option options [true] :require lists scope as required
18
24
  def initialize(name, options)
19
25
  @method_name = name
20
- @param_keys = [options.delete(:key)].flatten
26
+ @param_keys = Array(options.delete(:key))
27
+
28
+ @required_keys = register_keys(options[:require])
29
+ @whitelisted_keys = register_keys(options[:allow_nil])
30
+
31
+ if @whitelisted_keys.empty? && !@required_keys.empty?
32
+ @whitelisted_keys = @param_keys - @required_keys
33
+ end
21
34
 
22
35
  @options = options.freeze
23
36
  end
24
37
 
25
38
 
26
- # Checks if scope is required for query
27
- def required?
28
- !options[:require].nil?
39
+ # True if scope is required for query
40
+ # @param [Symbol, String] key param key being checked
41
+ def required?(key)
42
+ required_keys.include?(key)
43
+ end
44
+
45
+
46
+ # True if nil param values can be passed to scope
47
+ # @see #required?
48
+ def whitelisted?(key)
49
+ whitelisted_keys.include?(key)
29
50
  end
30
51
 
31
52
 
@@ -39,17 +60,24 @@ module Paraphrase
39
60
  # @param [ActiveRecord::Relation, ActiveRecord::Base] chain current model scope
40
61
  # @return [ActiveRecord::Relation]
41
62
  def chain(query, params, chain)
42
- inputs = param_keys.map { |key| params[key] }
63
+ inputs = param_keys.map do |key|
64
+ input = params[key]
43
65
 
44
- if inputs.include?(nil)
45
- param_keys.each do |key|
46
- query.errors.add(key, 'is required')
47
- end if required?
66
+ if input.nil? && ( required?(key) || !whitelisted?(key) )
67
+ query.errors.add(key, 'is required') if required?(key)
68
+ break []
69
+ end
48
70
 
49
- chain
50
- else
51
- chain.send(method_name, *inputs)
71
+ input
52
72
  end
73
+
74
+ inputs.empty? ? chain : chain.send(method_name, *inputs)
75
+ end
76
+
77
+ private
78
+
79
+ def register_keys(option)
80
+ option == true ? Array(param_keys) : Array(option)
53
81
  end
54
82
  end
55
83
  end
@@ -1,11 +1,18 @@
1
1
  module Paraphrase
2
2
  module Syntax
3
3
 
4
- # Register a {Query} class mapped to `self`.
4
+ # Register a {Query} class mapped to `self`. If the mapping has already
5
+ # been registered, calling again will clear existing scopes and evaluate
6
+ # the block.
5
7
  #
6
8
  # @param [Proc] &block block to define scope mappings
7
9
  def register_mapping(&block)
8
- Paraphrase.register(self.name, &block)
10
+ if mapping = Paraphrase.mapping(self.name.underscore)
11
+ mapping.scopes.clear
12
+ mapping.instance_eval(&block)
13
+ else
14
+ Paraphrase.register(self.name, &block)
15
+ end
9
16
  end
10
17
 
11
18
 
@@ -1,3 +1,3 @@
1
1
  module Paraphrase
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/paraphrase.gemspec CHANGED
@@ -6,11 +6,14 @@ Gem::Specification.new do |gem|
6
6
  gem.name = "paraphrase"
7
7
  gem.version = Paraphrase::VERSION
8
8
  gem.summary = %q{Map param keys to class scopes}
9
- gem.description = %q{Map param keys to class scopes}
9
+ gem.description = %q{
10
+ Build customizable classes to determine which scope
11
+ methods to call based on supplied parameters.
12
+ }
10
13
  gem.license = "MIT"
11
14
  gem.authors = ["Eduardo Gutierrez"]
12
15
  gem.email = "edd_d@mit.edu"
13
- gem.homepage = "https://rubygems.org/gems/paraphrase"
16
+ gem.homepage = "https://github.com/ecbypi/paraphrase"
14
17
 
15
18
  gem.files = `git ls-files`.split($/)
16
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -2,35 +2,47 @@ require 'spec_helper'
2
2
 
3
3
  module Paraphrase
4
4
  describe ScopeMapping do
5
- let(:scope_mapping) do
6
- ScopeMapping.new :name_like, :key => :name
7
- end
8
-
9
- it "removes keys from options" do
10
- scope_mapping.options.should_not have_key :key
5
+ let(:mapping) { ScopeMapping.new(:name_like, :key => :name) }
6
+ let(:compound_mapping) { ScopeMapping.new(:name_like, :key => [:first_name, :last_name], :require => :last_name) }
7
+ let(:query) do
8
+ query = double('query')
9
+ query.stub(:errors).and_return(double('errors'))
10
+ query
11
11
  end
12
12
 
13
13
  describe "#chain" do
14
- let(:query) { double('query') }
15
-
16
14
  it "applies scope method to query object with values from params hash" do
17
15
  Account.should_receive(:name_like).with('Jon Snow')
18
- scope_mapping.chain(query, { :name => 'Jon Snow' }, Account)
16
+ mapping.chain(query, { :name => 'Jon Snow' }, Account)
19
17
  end
20
18
 
21
19
  it "does nothing if values are missing" do
22
20
  Account.should_not_receive(:name_like).with('Jon Snow')
23
- scope_mapping.chain(query, {}, Account)
21
+ mapping.chain(query, {}, Account)
24
22
  end
25
23
 
26
24
  it "adds errors to query object if missing and required" do
27
- errors = double('errors')
28
- query.stub(:errors).and_return(errors)
29
- required_mapping = ScopeMapping.new :name_like, :key => :name, :require => true
25
+ required_mapping = ScopeMapping.new(:name_like, :key => :name, :require => true)
30
26
 
31
- errors.should_receive(:add)
27
+ query.errors.should_receive(:add)
32
28
  required_mapping.chain(query, {}, Account)
33
29
  end
30
+
31
+ it "passes through nil values if scope has been whitelisted" do
32
+ mapping = ScopeMapping.new(:name_like, :key => :name, :allow_nil => true)
33
+
34
+ Account.should_receive(:name_like).with(nil)
35
+ mapping.chain(query, {}, Account)
36
+ end
37
+ end
38
+
39
+ it "can require a subset of a compound key" do
40
+ Account.should_receive(:name_like).with(nil, 'Lannister')
41
+ compound_mapping.chain(query, { :last_name => 'Lannister' }, Account)
42
+ end
43
+
44
+ it "whitelists the the non-required keys of a compound key" do
45
+ compound_mapping.whitelisted?(:first_name).should be_true
34
46
  end
35
47
  end
36
48
  end
@@ -7,6 +7,15 @@ module Paraphrase
7
7
  ::Account.register_mapping {}
8
8
  Paraphrase.mapping(:account).should_not be_nil
9
9
  end
10
+
11
+ it "updates scopes if already registered" do
12
+ ::Account.register_mapping do
13
+ scope :name_like, :key => :name
14
+ end
15
+
16
+ mapping = Paraphrase.mapping(:account)
17
+ mapping.scopes.should_not be_empty
18
+ end
10
19
  end
11
20
 
12
21
  describe ".paraphrase" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paraphrase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-23 00:00:00.000000000 Z
12
+ date: 2012-07-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &70178168974020 !ruby/object:Gem::Requirement
16
+ requirement: &70300799182120 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70178168974020
24
+ version_requirements: *70300799182120
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70178168972120 !ruby/object:Gem::Requirement
27
+ requirement: &70300799180260 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70178168972120
35
+ version_requirements: *70300799180260
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activemodel
38
- requirement: &70178168971600 !ruby/object:Gem::Requirement
38
+ requirement: &70300799177960 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '3.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70178168971600
46
+ version_requirements: *70300799177960
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70178168971060 !ruby/object:Gem::Requirement
49
+ requirement: &70300799176700 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '1.0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70178168971060
57
+ version_requirements: *70300799176700
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: yard
60
- requirement: &70178168970400 !ruby/object:Gem::Requirement
60
+ requirement: &70300799167400 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0.7'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70178168970400
68
+ version_requirements: *70300799167400
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70178168969700 !ruby/object:Gem::Requirement
71
+ requirement: &70300799166180 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '2.10'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70178168969700
79
+ version_requirements: *70300799166180
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: redcarpet
82
- requirement: &70178168969060 !ruby/object:Gem::Requirement
82
+ requirement: &70300799164540 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70178168969060
90
+ version_requirements: *70300799164540
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rake
93
- requirement: &70178168968360 !ruby/object:Gem::Requirement
93
+ requirement: &70300799163600 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70178168968360
101
+ version_requirements: *70300799163600
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: sqlite3
104
- requirement: &70178168967600 !ruby/object:Gem::Requirement
104
+ requirement: &70300799162540 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70178168967600
112
+ version_requirements: *70300799162540
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: appraisal
115
- requirement: &70178168966640 !ruby/object:Gem::Requirement
115
+ requirement: &70300799161860 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,19 +120,20 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70178168966640
124
- description: Map param keys to class scopes
123
+ version_requirements: *70300799161860
124
+ description: ! "\n Build customizable classes to determine
125
+ which scope\n methods to call based on supplied parameters.\n
126
+ \ "
125
127
  email: edd_d@mit.edu
126
128
  executables: []
127
129
  extensions: []
128
130
  extra_rdoc_files: []
129
131
  files:
130
- - .document
131
132
  - .gitignore
132
133
  - .rspec
133
134
  - .yardopts
134
135
  - Appraisals
135
- - ChangeLog.md
136
+ - CHANGELOG
136
137
  - Gemfile
137
138
  - LICENSE.txt
138
139
  - README.md
@@ -156,7 +157,7 @@ files:
156
157
  - spec/paraphrase/syntax_spec.rb
157
158
  - spec/paraphrase_spec.rb
158
159
  - spec/spec_helper.rb
159
- homepage: https://rubygems.org/gems/paraphrase
160
+ homepage: https://github.com/ecbypi/paraphrase
160
161
  licenses:
161
162
  - MIT
162
163
  post_install_message:
data/.document DELETED
@@ -1,3 +0,0 @@
1
- -
2
- ChangeLog.md
3
- LICENSE.txt
data/ChangeLog.md DELETED
@@ -1,4 +0,0 @@
1
- ### 0.1.0 / 2012-06-04
2
-
3
- * Initial release:
4
-