active_record_relation_in 0.1.0
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.
- checksums.yaml +7 -0
- data/README.md +75 -0
- data/lib/active_record_relation_in/version.rb +5 -0
- data/lib/active_record_relation_in/where_clause/combine_with_in_relation.rb +65 -0
- data/lib/active_record_relation_in/where_clause/relation_patch.rb +17 -0
- data/lib/active_record_relation_in/where_clause/where_clause_patch.rb +13 -0
- data/lib/active_record_relation_in.rb +30 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ce1d6dc9172035c97ed5360be175b27798667d8aaca6a88d3dc6077fb3d1f84
|
4
|
+
data.tar.gz: a68c0e828707ee8010ebf1a4371523948baf3a24beb991dca01e47e00fa1a3b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 84a88ba27d53ee59bb12aa6a753ef1c3d017a00b8ee6dec66d1a3baaab859877e438f685e1aa37da4151d72b5e76482767b0ab710405db21845d648818501ec9
|
7
|
+
data.tar.gz: 1fd5a4e73d28459c59c7e97cb4e08459c1f94acd4d775724842fdcc7f5acd69f5eb8969b140eb6dfbbb11c5dc1a9458bb65f2ad053603884c1df7e8b05ff7fb4
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
## Index
|
2
|
+
- [Description and history](#description-and-history)
|
3
|
+
- [Compatibility](#compatibility)
|
4
|
+
- [Installation](#installation)
|
5
|
+
- [Usage](#usage)
|
6
|
+
- [Scope Modifiers](#scope-modifiers)
|
7
|
+
- [Combine With IN](#combine-with-in)
|
8
|
+
|
9
|
+
## Description and History
|
10
|
+
|
11
|
+
Active Record Relation In grew out of the frustration that certain combining of scopes would make them not function.
|
12
|
+
|
13
|
+
By default ActiveRecord combines different where statements with an AND statement. This makes it hard to write scopes that can be combined without doing a lot of trickery.
|
14
|
+
|
15
|
+
Active Record Relation In is the continuation of maintaining and improving the work done by **George Protacio-Karaszi**, the original author of [active_record_extended](https://github.com/GeorgeKaraszi/ActiveRecordExtended).
|
16
|
+
|
17
|
+
Since it's a great start of how to make sure combines correctly with Active Record and this feature was a bit to specific for them to want in their gem.
|
18
|
+
|
19
|
+
## Compatibility
|
20
|
+
|
21
|
+
This package is designed align and work with any officially supported Ruby and Rails versions.
|
22
|
+
- Minimum Ruby Version: 3.1.x **(EOL warning!)**
|
23
|
+
- Minimum Rails Version: 6.1.x **(EOL warning!)**
|
24
|
+
- Minimum Postgres Version: 12.x **(EOL warning!)**
|
25
|
+
- Latest Ruby supported: 3.3.x
|
26
|
+
- Latest Rails supported: 7.1.x
|
27
|
+
- Postgres: 11-current(16) (probably works with most older versions to a certain point)
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
Add this line to your application's Gemfile:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
gem 'active_record_relation_in'
|
35
|
+
```
|
36
|
+
|
37
|
+
And then execute:
|
38
|
+
|
39
|
+
$ bundle
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
#### Scope Modifiers
|
44
|
+
|
45
|
+
#### Combine With IN
|
46
|
+
|
47
|
+
When you want to combine with statement with an IN statement instead of the usual AND statement
|
48
|
+
|
49
|
+
`.combine_with_in/0`
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
class User < ApplicationRecord
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
class Tag < ApplicationRecord
|
57
|
+
belongs_to :user
|
58
|
+
scope :for_users, ->(user_ids) { where(user_id: user_ids).combine_with_in }
|
59
|
+
end
|
60
|
+
|
61
|
+
Tag.where(id: 1).for_users([1, 2]).for_users(3)
|
62
|
+
```
|
63
|
+
|
64
|
+
Query Output
|
65
|
+
```sql
|
66
|
+
SELECT "tags".*
|
67
|
+
FROM "tags"
|
68
|
+
WHERE
|
69
|
+
"tags"."id" = 1 AND
|
70
|
+
"tags"."user_id" IN (1, 2, 3)
|
71
|
+
```
|
72
|
+
|
73
|
+
## License
|
74
|
+
|
75
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecordRelationIn
|
4
|
+
module WhereClause
|
5
|
+
class CombineWithInRelation < ActiveRecord::Relation::WhereClause
|
6
|
+
def ast
|
7
|
+
predicates = predicates_with_wrapped_sql_literals
|
8
|
+
return predicates.first if predicates.one?
|
9
|
+
|
10
|
+
equality_predicats, other_predicats = split_predicates(predicates)
|
11
|
+
|
12
|
+
return Arel::Nodes::And.new(predicates) if equality_predicats.empty?
|
13
|
+
|
14
|
+
ast_for_equality_predicates(equality_predicats, other_predicats)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def ast_for_equality_predicates(equality_predicats, other_predicats)
|
20
|
+
grouped_equality_predicates = equality_predicats.group_by { |equality_predicat| equality_predicat.right.name }
|
21
|
+
if grouped_equality_predicates.one? && other_predicats.empty?
|
22
|
+
values = predicate_values(predicates)
|
23
|
+
attribute = predicates.first.left
|
24
|
+
Arel::Nodes::HomogeneousIn.new(values, attribute, :in)
|
25
|
+
else
|
26
|
+
combined_predicates = other_predicats + equality_predicates(grouped_equality_predicates)
|
27
|
+
Arel::Nodes::And.new(combined_predicates)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def predicate_values(predicates)
|
32
|
+
predicates.map do |predicate|
|
33
|
+
value = predicate.right.value
|
34
|
+
if value.instance_of?(Hash)
|
35
|
+
value.map { |key, hash_values| hash_values.map { |hash_value| hash_value[key] } }
|
36
|
+
else
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
def split_predicates(predicates)
|
43
|
+
predicates.each_with_object([[], []]) do |predicate, acc|
|
44
|
+
if predicate.instance_of?(Arel::Nodes::Equality)
|
45
|
+
[acc.first.push(predicate), acc.last]
|
46
|
+
else
|
47
|
+
[acc.first, acc.last.push(predicate)]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def equality_predicates(grouped_equality_predicates)
|
53
|
+
grouped_equality_predicates.values.map do |predicates_by_name|
|
54
|
+
if predicates_by_name.one?
|
55
|
+
predicates_by_name.first
|
56
|
+
else
|
57
|
+
values = predicate_values(predicates_by_name)
|
58
|
+
attribute = predicates_by_name.first.left
|
59
|
+
Arel::Nodes::HomogeneousIn.new(values, attribute, :in)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecordRelationIn
|
4
|
+
module WhereClause
|
5
|
+
module RelationPatch
|
6
|
+
module RelationCombineInPatch
|
7
|
+
def combine_with_in
|
8
|
+
self.where_clause = where_clause.combine_with_in
|
9
|
+
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveRecord::Relation.prepend(ActiveRecordRelationIn::WhereClause::RelationPatch::RelationCombineInPatch)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecordRelationIn
|
4
|
+
module WhereClause
|
5
|
+
module WhereClausePatch
|
6
|
+
def combine_with_in
|
7
|
+
ActiveRecordRelationIn::WhereClause::CombineWithInRelation.new(@predicates)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveRecord::Relation::WhereClause.prepend(ActiveRecordRelationIn::WhereClause::WhereClausePatch)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "active_record_relation_in/version"
|
4
|
+
|
5
|
+
require "active_record"
|
6
|
+
|
7
|
+
module ActiveRecordRelationIn
|
8
|
+
extend ActiveSupport::Autoload
|
9
|
+
|
10
|
+
AR_VERSION_GTE_6_1 = Gem::Requirement.new(">= 6.1").satisfied_by?(ActiveRecord.gem_version)
|
11
|
+
|
12
|
+
module WhereClause
|
13
|
+
extend ActiveSupport::Autoload
|
14
|
+
|
15
|
+
eager_autoload do
|
16
|
+
autoload :RelationPatch
|
17
|
+
autoload :WhereClausePatch
|
18
|
+
autoload :CombineWithInRelation
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.eager_load!
|
23
|
+
super
|
24
|
+
ActiveRecordRelationIn::WhereClause.eager_load!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
ActiveSupport.on_load(:active_record) do
|
29
|
+
ActiveRecordRelationIn.eager_load!
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record_relation_in
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Olafur Arason
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-03-16 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: activerecord
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '5.2'
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '8.1'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '5.2'
|
29
|
+
- - "<"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '8.1'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: pg
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "<"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '3.0'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - "<"
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.0'
|
46
|
+
description: Adds relation in functionality to Activerecord Postgres implementation
|
47
|
+
email:
|
48
|
+
- olafura@olafura.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- README.md
|
54
|
+
- lib/active_record_relation_in.rb
|
55
|
+
- lib/active_record_relation_in/version.rb
|
56
|
+
- lib/active_record_relation_in/where_clause/combine_with_in_relation.rb
|
57
|
+
- lib/active_record_relation_in/where_clause/relation_patch.rb
|
58
|
+
- lib/active_record_relation_in/where_clause/where_clause_patch.rb
|
59
|
+
homepage: https://github.com/olafura/active_record_relation_in
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata:
|
63
|
+
rubygems_mfa_required: 'true'
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '3.1'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubygems_version: 3.6.2
|
79
|
+
specification_version: 4
|
80
|
+
summary: Adds relation in functionality to Activerecord Postgres implementation
|
81
|
+
test_files: []
|