rails_or 1.1.8 → 1.1.9

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/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
7
  t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
- task :default => :test
10
+ task default: :test
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "rails_or"
3
+ require 'bundler/setup'
4
+ require 'rails_or'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "rails_or"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install --gemfile=gemfiles/4.2.gemfile
7
-
8
- # Do any other automated setup that you need to do here
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install --gemfile=gemfiles/4.2.gemfile
7
+
8
+ # Do any other automated setup that you need to do here
data/gemfiles/3.2.gemfile CHANGED
@@ -1,13 +1,10 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rails_or.gemspec
4
-
5
- gem "activerecord", "~> 3.2"
6
-
7
- group :test do
8
- gem "simplecov"
9
- gem "codeclimate-test-reporter", "~> 1.0.0"
10
- end
11
-
12
- gemspec :path => "../"
13
-
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 3.2.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ end
9
+
10
+ gemspec path: '../'
data/gemfiles/4.2.gemfile CHANGED
@@ -1,13 +1,10 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rails_or.gemspec
4
-
5
- gem "activerecord", "~> 4.2"
6
-
7
- group :test do
8
- gem "simplecov"
9
- gem "codeclimate-test-reporter", "~> 1.0.0"
10
- end
11
-
12
- gemspec :path => "../"
13
-
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.2.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ end
9
+
10
+ gemspec path: '../'
data/gemfiles/5.0.gemfile CHANGED
@@ -1,13 +1,10 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rails_or.gemspec
4
-
5
- gem "activerecord", "~> 5.0"
6
-
7
- group :test do
8
- gem "simplecov"
9
- gem "codeclimate-test-reporter", "~> 1.0.0"
10
- end
11
-
12
- gemspec :path => "../"
13
-
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.0.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ end
9
+
10
+ gemspec path: '../'
data/gemfiles/5.1.gemfile CHANGED
@@ -1,13 +1,10 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rails_or.gemspec
4
-
5
- gem "activerecord", "~> 5.1"
6
-
7
- group :test do
8
- gem "simplecov"
9
- gem "codeclimate-test-reporter", "~> 1.0.0"
10
- end
11
-
12
- gemspec :path => "../"
13
-
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.1.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ end
9
+
10
+ gemspec path: '../'
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.2.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ end
9
+
10
+ gemspec path: '../'
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 6.0.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.4.1'
8
+ end
9
+
10
+ gemspec path: '../'
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 6.1.0'
4
+
5
+ group :test do
6
+ gem 'simplecov', '< 0.18'
7
+ gem 'sqlite3', '~> 1.4.1'
8
+ end
9
+
10
+ gemspec path: '../'
data/lib/rails_or.rb CHANGED
@@ -1,119 +1,63 @@
1
- require "rails_or/version"
2
- require "rails_or/where_binding_mixs"
3
- require 'active_record'
4
-
5
- if defined?(ActiveRecord::NullRelation)
6
- module ActiveRecord::NullRelation
7
- if method_defined?(:or)
8
- if not method_defined?(:rails5_or)
9
- alias_method :rails5_or, :or
10
- def or(*other)
11
- rails5_or(rails_or_parse_parameter(*other))
12
- end
13
- end
14
- end
15
- end
16
- end
17
-
18
- class ActiveRecord::Relation
19
- IS_RAILS3_FLAG = Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.0')
20
- IS_RAILS5_FLAG = Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('5.0.0')
21
- FROM_VALUE_METHOD = %i[from_value from_clause].find{|s| method_defined?(s) }
22
- ASSIGN_FROM_VALUE = :"#{FROM_VALUE_METHOD}="
23
- if method_defined?(:or)
24
- if not method_defined?(:rails5_or)
25
- alias_method :rails5_or, :or
26
- def or(*other)
27
- return rails5_or(rails_or_parse_parameter(*other))
28
- end
29
- end
30
- else
31
- def or(*other)
32
- other = rails_or_parse_parameter(*other)
33
- combining = group_values.any? ? :having : :where
34
- left = RailsOr::WhereBindingMixs.new(self.send("#{combining}_values"), self.bind_values)
35
- right = RailsOr::WhereBindingMixs.new(other.send("#{combining}_values"), other.bind_values)
36
- common = left & right
37
-
38
- left -= common
39
- right -= common
40
-
41
- if left.where_values.any? && right.where_values.any?
42
- arel_or = Arel::Nodes::Or.new(
43
- rails_or_values_to_arel(left.where_values),
44
- rails_or_values_to_arel(right.where_values),
45
- )
46
- common += RailsOr::WhereBindingMixs.new([arel_or], left.bind_values + right.bind_values)
47
- end
48
-
49
- relation = rails_or_get_current_scope
50
- if defined?(ActiveRecord::NullRelation) # Rails 3 does not have ActiveRecord::NullRelation
51
- return other if relation.is_a?(ActiveRecord::NullRelation)
52
- return relation if other.is_a?(ActiveRecord::NullRelation)
53
- end
54
- relation.send("#{combining}_values=", common.where_values)
55
- relation.bind_values = common.bind_values
56
- return relation
57
- end
58
- end
59
-
60
- def or_not(*args) # Works in Rails 4+
61
- self.or(klass.where.not(*args))
62
- end
63
-
64
- def or_having(hash)
65
- self.or(rails_or_spwan_relation(:having, hash))
66
- end
67
-
68
- private
69
-
70
- def rails_or_values_to_arel(values)
71
- values.map!{|x| rails_or_wrap_arel(x) }
72
- return (values.size > 1 ? Arel::Nodes::And.new(values) : values)
73
- end
74
-
75
- def rails_or_wrap_arel(node)
76
- return node if Arel::Nodes::Equality === node
77
- return Arel::Nodes::Grouping.new(String === node ? Arel.sql(node) : node)
78
- end
79
-
80
- def rails_or_parse_parameter(*other)
81
- other = other.first if other.size == 1
82
- case other
83
- when Hash ; rails_or_spwan_relation(:where, other)
84
- when Array ; rails_or_spwan_relation(:where, other)
85
- when String ; rails_or_spwan_relation(:where, other)
86
- else ; other
87
- end
88
- end
89
-
90
- def rails_or_copy_values_to(relation) # For Rails 5
91
- relation.joins_values = self.joins_values
92
- relation.limit_value = self.limit_value
93
- relation.group_values = self.group_values
94
- relation.distinct_value = self.distinct_value
95
- relation.order_values = self.order_values
96
- relation.offset_value = self.offset_value
97
- relation.references_values = self.references_values
98
- end
99
-
100
- def rails_or_spwan_relation(method, condition)
101
- relation = klass.send(method, condition)
102
- relation.send(ASSIGN_FROM_VALUE, send(FROM_VALUE_METHOD))
103
- rails_or_copy_values_to(relation) if IS_RAILS5_FLAG
104
- return relation
105
- end
106
-
107
- def rails_or_get_current_scope
108
- return self.clone if IS_RAILS3_FLAG
109
- # ref: https://github.com/rails/rails/blob/17ef58db1776a795c9f9e31a1634db7bcdc3ecdf/activerecord/lib/active_record/scoping/named.rb#L26
110
- # return self.all # <- cannot use this because some gem changes this method's behavior
111
- return (self.current_scope || self.default_scoped).clone
112
- end
113
- end
114
-
115
- class ActiveRecord::Base
116
- def self.or(*args)
117
- self.where('').or(*args)
118
- end
119
- end
1
+ require 'rails_or/version'
2
+ require 'rails_or/where_binding_mixs'
3
+ require 'active_record'
4
+ require 'rails_or/patches/null_relation' if defined?(ActiveRecord::NullRelation)
5
+ require 'rails_or/active_record/extension'
6
+
7
+ module RailsOr
8
+ IS_RAILS3_FLAG = Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.0')
9
+ IS_RAILS5_FLAG = Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('5.0.0')
10
+ FROM_VALUE_METHOD = %i[from_value from_clause].find{|s| ActiveRecord::Relation.method_defined?(s) }
11
+ ASSIGN_FROM_VALUE = :"#{FROM_VALUE_METHOD}="
12
+
13
+ class << self
14
+ def values_to_arel(values)
15
+ values.map!{|x| wrap_arel(x) }
16
+ return (values.size > 1 ? Arel::Nodes::And.new(values) : values)
17
+ end
18
+
19
+ def spawn_relation(relation, method, condition)
20
+ new_relation = relation.klass.send(method, condition)
21
+
22
+ from_value = relation.send(FROM_VALUE_METHOD)
23
+ new_relation.send(ASSIGN_FROM_VALUE, from_value) if from_value.present?
24
+
25
+ copy_values(new_relation, relation) if IS_RAILS5_FLAG
26
+ return new_relation
27
+ end
28
+
29
+ def get_current_scope(relation)
30
+ return relation.clone if IS_RAILS3_FLAG
31
+ # ref: https://github.com/rails/rails/blob/17ef58db1776a795c9f9e31a1634db7bcdc3ecdf/activerecord/lib/active_record/scoping/named.rb#L26
32
+ # return relation.all # <- cannot use this because some gem changes this method's behavior
33
+ return (relation.current_scope || relation.default_scoped).clone
34
+ end
35
+
36
+ def parse_parameter(relation, *other)
37
+ other = other.first if other.size == 1
38
+ case other
39
+ when Hash ; spawn_relation(relation, :where, other)
40
+ when Array ; spawn_relation(relation, :where, other)
41
+ when String ; spawn_relation(relation, :where, other)
42
+ else ; other
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def wrap_arel(node)
49
+ return node if Arel::Nodes::Equality === node
50
+ return Arel::Nodes::Grouping.new(String === node ? Arel.sql(node) : node)
51
+ end
52
+
53
+ def copy_values(to, from) # For Rails 5, 6
54
+ to.joins_values = from.joins_values if from.joins_values.any?
55
+ to.limit_value = from.limit_value
56
+ to.group_values = from.group_values if from.group_values.any?
57
+ to.distinct_value = from.distinct_value
58
+ to.order_values = from.order_values if from.order_values.any?
59
+ to.offset_value = from.offset_value
60
+ to.references_values = from.references_values
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,52 @@
1
+ class ActiveRecord::Relation
2
+ if method_defined?(:or)
3
+ if not method_defined?(:rails5_or)
4
+ alias rails5_or or
5
+ def or(*other)
6
+ rails5_or(RailsOr.parse_parameter(self, *other))
7
+ end
8
+ end
9
+ else
10
+ def or(*other)
11
+ other = RailsOr.parse_parameter(self, *other)
12
+ combining = group_values.any? ? :having : :where
13
+ left = RailsOr::WhereBindingMixs.new(send("#{combining}_values"), bind_values)
14
+ right = RailsOr::WhereBindingMixs.new(other.send("#{combining}_values"), other.bind_values)
15
+ common = left & right
16
+
17
+ left -= common
18
+ right -= common
19
+
20
+ if left.where_values.any? && right.where_values.any?
21
+ arel_or = Arel::Nodes::Or.new(
22
+ RailsOr.values_to_arel(left.where_values),
23
+ RailsOr.values_to_arel(right.where_values),
24
+ )
25
+ common += RailsOr::WhereBindingMixs.new([arel_or], left.bind_values + right.bind_values)
26
+ end
27
+
28
+ relation = RailsOr.get_current_scope(self)
29
+ if defined?(ActiveRecord::NullRelation) # Rails 3 does not have ActiveRecord::NullRelation
30
+ return other if relation.is_a?(ActiveRecord::NullRelation)
31
+ return relation if other.is_a?(ActiveRecord::NullRelation)
32
+ end
33
+ relation.send("#{combining}_values=", common.where_values)
34
+ relation.bind_values = common.bind_values
35
+ return relation
36
+ end
37
+ end
38
+
39
+ def or_not(*args) # Works in Rails 4+
40
+ self.or(klass.where.not(*args))
41
+ end
42
+
43
+ def or_having(hash)
44
+ self.or(RailsOr.spawn_relation(self, :having, hash))
45
+ end
46
+ end
47
+
48
+ class ActiveRecord::Base
49
+ def self.or(*args)
50
+ where('').or(*args)
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ module ActiveRecord::NullRelation
2
+ if method_defined?(:or) and not method_defined?(:rails5_or)
3
+ alias rails5_or or
4
+ def or(*other)
5
+ rails5_or(RailsOr.parse_parameter(self, *other))
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
- module RailsOr
2
- VERSION = "1.1.8"
3
- end
1
+ module RailsOr
2
+ VERSION = '1.1.9'
3
+ end
@@ -1,38 +1,38 @@
1
- class RailsOr::WhereBindingMixs
2
- attr_reader :where_values
3
- attr_reader :bind_values
4
-
5
- def initialize(where_values, bind_values)
6
- @where_values = where_values
7
- @bind_values = bind_values
8
- end
9
-
10
- def +(other)
11
- self.class.new(@where_values + other.where_values, @bind_values + other.bind_values)
12
- end
13
-
14
- def -(other)
15
- self.select{|node| !other.where_values.include?(node) }
16
- end
17
-
18
- def &(other)
19
- common_where_values = @where_values & other.where_values
20
- return self.select{|node| common_where_values.include?(node) }
21
- end
22
-
23
- def select
24
- binds_index = 0
25
- new_bind_values = []
26
- new_where_values = @where_values.select do |node|
27
- flag = yield(node)
28
- if not node.is_a?(String)
29
- binds_contains = node.grep(Arel::Nodes::BindParam).size
30
- pre_binds_index = binds_index
31
- binds_index += binds_contains
32
- (pre_binds_index...binds_index).each{|i| new_bind_values << @bind_values[i] } if flag
33
- end
34
- next flag
35
- end
36
- return self.class.new(new_where_values, new_bind_values)
37
- end
38
- end
1
+ class RailsOr::WhereBindingMixs
2
+ attr_reader :where_values
3
+ attr_reader :bind_values
4
+
5
+ def initialize(where_values, bind_values)
6
+ @where_values = where_values
7
+ @bind_values = bind_values
8
+ end
9
+
10
+ def +(other)
11
+ self.class.new(@where_values + other.where_values, @bind_values + other.bind_values)
12
+ end
13
+
14
+ def -(other)
15
+ select{|node| !other.where_values.include?(node) }
16
+ end
17
+
18
+ def &(other)
19
+ common_where_values = @where_values & other.where_values
20
+ return select{|node| common_where_values.include?(node) }
21
+ end
22
+
23
+ def select
24
+ binds_index = 0
25
+ new_bind_values = []
26
+ new_where_values = @where_values.select do |node|
27
+ flag = yield(node)
28
+ if not node.is_a?(String)
29
+ binds_contains = node.grep(Arel::Nodes::BindParam).size
30
+ pre_binds_index = binds_index
31
+ binds_index += binds_contains
32
+ (pre_binds_index...binds_index).each{|i| new_bind_values << @bind_values[i] } if flag
33
+ end
34
+ next flag
35
+ end
36
+ return self.class.new(new_where_values, new_bind_values)
37
+ end
38
+ end