activerecord-like 0.0.5 → 0.0.6

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.
@@ -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'