activerecord-like 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6e1d444430a4d71fcf388e809bc133ef37b6d6f2
4
+ data.tar.gz: 6dbf791db767395263eb645522e5edbe65294222
5
+ SHA512:
6
+ metadata.gz: 66da03780c19dcd40e345e855ebffc9f22eac25402d8a872758e8d8d44022833dbe39ef1d80d3cbd5e73ca0f750f10ab0b1ba9bf2b2b98433bec80e16d3a1f68
7
+ data.tar.gz: b5a30f2872aa5034fcd0ebd3933b45b6da89781d8d60f9be477034643b01004fb9e2d52feb47092be42bb973a90336e4fb2f8d710d57ac1fc7a35536ebba4f08
data/README.md CHANGED
@@ -10,6 +10,7 @@
10
10
  An Active Record Plugin that allows chaining a more DSL-style 'like' or 'not-like' query to an ActiveRecord::Base#where. Requires Rails 4 beta or higher.
11
11
 
12
12
  This plugin has been salvaged from the stellar work done by @amatsuda and @claudiob. Most of the code was previously in Active Record master, but was subsequently removed due to, amongst other, scope creep.
13
+ Array parameter handling was added by @rzane - thanks!
13
14
 
14
15
  ## Installation
15
16
 
@@ -31,14 +32,19 @@ Given a class Post and the WhereChain work in Active Record, this plugin allows
31
32
 
32
33
  ```ruby
33
34
  Post.where.like(title: "%rails%")
35
+ Post.where.like(title: ["%ruby%", "%rails%"])
34
36
  ```
35
37
 
36
38
  and
37
39
 
38
40
  ```ruby
39
41
  Post.where.not_like(title: "%rails%")
42
+ Post.where.not_like(title: ["%ruby%", "%rails%"])
40
43
  ```
41
44
 
45
+ ## Dependencies
46
+ Does not work with ARel 4.0.1 or lower or ARel 5.0.0. Do a `bundle update arel` to get the latest ARel that is compatible with your ActiveRecord version (4.0 for ActiveRecord 4.0, 5.0 for ActiveRecord 4.1).
47
+
42
48
  ## Contributing
43
49
 
44
50
  1. Fork it
@@ -4,18 +4,29 @@ module ActiveRecord
4
4
  module QueryMethods
5
5
  module Like
6
6
  def like(opts, *rest)
7
- chain_node(Arel::Nodes::Matches, opts, *rest)
7
+ chain_node(Arel::Nodes::Matches, opts, *rest) do |nodes|
8
+ nodes.inject { |memo, node| Arel::Nodes::Or.new(memo, node) }
9
+ end
8
10
  end
9
11
 
10
12
  def not_like(opts, *rest)
11
- chain_node(Arel::Nodes::DoesNotMatch, opts, *rest)
13
+ opts = opts.reject { |_, v| v.is_a?(Array) && v.empty? }
14
+ chain_node(Arel::Nodes::DoesNotMatch, opts, *rest) do |nodes|
15
+ Arel::Nodes::And.new(nodes)
16
+ end
12
17
  end
13
18
 
14
19
  private
15
- def chain_node(node_type, opts, *rest)
20
+
21
+ def chain_node(node_type, opts, *rest, &block)
16
22
  @scope.tap do |s|
17
23
  s.where_values += s.send(:build_where, opts, *rest).map do |r|
18
- node_type.new(r.left, r.right)
24
+ if r.right.is_a?(Array)
25
+ nodes = r.right.map { |expr| node_type.new(r.left, expr) }
26
+ Arel::Nodes::Grouping.new block.call(nodes)
27
+ else
28
+ node_type.new(r.left, r.right)
29
+ end
19
30
  end
20
31
  end
21
32
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Like
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
@@ -34,6 +34,20 @@ describe ActiveRecord::QueryMethods::WhereChain do
34
34
  Post.where.like(title: '%this title is not used anywhere%').map(&:id).wont_include 2
35
35
  end
36
36
 
37
+ describe "array behavior" do
38
+ it "finds records with attributes matching multiple criteria" do
39
+ Post.where.like(title: ['%DSLs%', 'We need some%']).map(&:id).must_equal [1, 2]
40
+ end
41
+
42
+ it "finds records with attributes matching one criterion" do
43
+ Post.where.like(title: ['%there?']).map(&:id).must_equal [2]
44
+ end
45
+
46
+ it "does not find any records with an empty array" do
47
+ Post.where.like(title: []).must_be_empty
48
+ end
49
+ end
50
+
37
51
  describe "security-related behavior" do
38
52
  before do
39
53
  @user_input = "unused%' OR 1=1); -- "
@@ -49,6 +63,10 @@ describe ActiveRecord::QueryMethods::WhereChain do
49
63
  it "prevents SQL injection" do
50
64
  Post.where.like(title: @user_input).count.must_equal(0)
51
65
  end
66
+
67
+ it "prevents SQL injection when provided an array" do
68
+ Post.where.like(title: [@user_input]).count.must_equal(0)
69
+ end
52
70
  end
53
71
  end
54
72
  end
@@ -34,6 +34,20 @@ describe ActiveRecord::QueryMethods::WhereChain do
34
34
  Post.where.not_like(title: '%this title is not used anywhere%').map(&:id).must_include 2
35
35
  end
36
36
 
37
+ describe "array behavior" do
38
+ it "finds records with attributes not matching multiple criteria" do
39
+ Post.where.not_like(title: ['%DSLs%', 'We need some%']).map(&:id).must_be_empty
40
+ end
41
+
42
+ it "finds records with attributes not matching one criterion" do
43
+ Post.where.not_like(title: ['%there?']).map(&:id).must_equal [1]
44
+ end
45
+
46
+ it "finds all records with an empty array" do
47
+ Post.where.not_like(title: []).count.must_equal 2
48
+ end
49
+ end
50
+
37
51
  describe "security-related behavior" do
38
52
  before do
39
53
  @user_input = "unused%' OR 1=1); -- "
@@ -49,7 +63,10 @@ describe ActiveRecord::QueryMethods::WhereChain do
49
63
  it "prevents SQL injection" do
50
64
  Post.where.not_like(title: @user_input).count.must_equal(2)
51
65
  end
66
+
67
+ it "prevents SQL injection when provided an array" do
68
+ Post.where.not_like(title: [@user_input]).count.must_equal(2)
69
+ end
52
70
  end
53
71
  end
54
72
  end
55
-
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-like
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
5
- prerelease:
4
+ version: 0.0.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - René van den Berg
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-04-15 00:00:00.000000000 Z
11
+ date: 2014-11-21 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 4.0.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 4.0.0
30
27
  description: An ActiveRecord plugin providing a higher-level abstraction for SQL 'LIKE'
@@ -35,8 +32,8 @@ executables: []
35
32
  extensions: []
36
33
  extra_rdoc_files: []
37
34
  files:
38
- - .gitignore
39
- - .travis.yml
35
+ - ".gitignore"
36
+ - ".travis.yml"
40
37
  - Gemfile
41
38
  - LICENSE.txt
42
39
  - README.md
@@ -52,34 +49,27 @@ files:
52
49
  - test/unit/not_like_test.rb
53
50
  homepage: http://github.com/ReneB/activerecord-like
54
51
  licenses: []
52
+ metadata: {}
55
53
  post_install_message:
56
54
  rdoc_options: []
57
55
  require_paths:
58
56
  - lib
59
57
  required_ruby_version: !ruby/object:Gem::Requirement
60
- none: false
61
58
  requirements:
62
- - - ! '>='
59
+ - - ">="
63
60
  - !ruby/object:Gem::Version
64
61
  version: '0'
65
- segments:
66
- - 0
67
- hash: -1166120551184225501
68
62
  required_rubygems_version: !ruby/object:Gem::Requirement
69
- none: false
70
63
  requirements:
71
- - - ! '>='
64
+ - - ">="
72
65
  - !ruby/object:Gem::Version
73
66
  version: '0'
74
- segments:
75
- - 0
76
- hash: -1166120551184225501
77
67
  requirements: []
78
68
  rubyforge_project:
79
- rubygems_version: 1.8.24
69
+ rubygems_version: 2.4.4
80
70
  signing_key:
81
- specification_version: 3
82
- summary: ! 'ActiveRecord::Like provides ActiveRecord::Base with where.like(attribute:
71
+ specification_version: 4
72
+ summary: 'ActiveRecord::Like provides ActiveRecord::Base with where.like(attribute:
83
73
  string)-style extensions. This functionality was, at one point, included in Rails-master,
84
74
  but subsequently removed. Since the feature seemed to be in some demand, I thought
85
75
  I''d try my hand at building an ActiveRecord plugin'