association_scope 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4e530681dac428e3085f151e36a1a44a1f04a82b7da9df1be7e76fd3d02b80e
4
- data.tar.gz: 05e2cf1a4c61eaef59bf93933827c118fa945be2f60a7079b1cd937e013259b7
3
+ metadata.gz: 4a78d72190a884c263ac9dac8d02588505bf530168c8e15faff4a3d3f07e53ad
4
+ data.tar.gz: ccd5422df4c1c871dacb0b0b8954abffb580ac305d639a8b91438f6ceb8abb85
5
5
  SHA512:
6
- metadata.gz: 03e14bf3ca5db469c9e253dead3b9953f13afc4f39bb485bd48dac4c7b549dfa850f9933ffe9045a6ee97543ea883b35d264f5956fac01d93156f66ebd4919e2
7
- data.tar.gz: ad322f4d8fe5a3e2860f421216f79bf4c129d652b0466c234a47970a4327c23659651cc1bfb4e344f7fa75356b3afac768eac08a272873a71201ca76a6cb1671
6
+ metadata.gz: 539e2a97b60ecf359a717e8dd4de6a203d16ea91e2fb61dd7a520bb599b79a4b7a5ac742a63f33bddbf199bc4565dfb728c85994cd30e5733a307e915d53ed1d
7
+ data.tar.gz: f2d1f90636e1e2f5aca7231ef8c8d686d276d5a341b02e6a5b70af77ad7b1c5500bf5ac1c45b64624e12315add3e6ffdbb72d61fddd5adc48e98c3216cd3db6a
data/README.md CHANGED
@@ -19,7 +19,7 @@ class Topic < ApplicationRecord
19
19
  scope :of_users, -> (users) { joins(:user).where(users: users) }
20
20
  end
21
21
  ```
22
- over and over again across all of my models to write `Topic.of_users(current_user.friends)` when I wanted to write `current_user.friends.topics` instead.
22
+ over and over again across all of my models to write something like `Topic.of_users(current_user.friends)` when I wanted to write `current_user.friends.topics` instead.
23
23
  And `belongs_to` is the easiest part.
24
24
 
25
25
  When you have this problem, the AssociationScope gem is for you!
@@ -57,6 +57,23 @@ Topic.all.users
57
57
  ```
58
58
  to retrieve the users of all of the topics of your application.
59
59
 
60
+ ### Migration from `.of_model`
61
+ When you already use any form of `.of_model` scope, you can replace it with association scopes:
62
+
63
+ ```ruby
64
+ # replace
65
+ Topic.of_users(current_user.friends)
66
+ # with
67
+ current_user.friends.topics
68
+ ```
69
+ When you chain scopes, you have to merge with the previous scope:
70
+ ```ruby
71
+ # replace
72
+ scope.of_users(users)
73
+ # with
74
+ users.topics.merge(scope)
75
+ ```
76
+
60
77
  ## Known Issues
61
78
  * This gem works with `reflections`.
62
79
  To make this work, the `has_association_scope_on` call has to be below your association definitions.
@@ -11,7 +11,7 @@ module AssociationScope
11
11
  end
12
12
 
13
13
  def message
14
- "Association #{association} missing in #{missing_in}!"
14
+ "Association :#{association} missing in #{missing_in}!"
15
15
  end
16
16
  end
17
17
  end
@@ -5,21 +5,11 @@ module AssociationScope
5
5
  class BelongsToReflection < Scope
6
6
  def apply
7
7
  association = @association
8
- details = model.reflections[association]
9
- class_name = details.options[:class_name]&.constantize || association.camelize.constantize
8
+ class_name = reflection_details.options[:class_name]&.constantize || association.camelize.constantize
9
+ foreign_key = reflection_details.options[:foreign_key]
10
10
  association_name = association.to_s.underscore.to_sym
11
- foreign_key = details.options[:foreign_key]
12
11
  own_table_name = class_name.to_s.pluralize.underscore
13
-
14
- inverse_reflection = class_name.reflections[model.to_s.underscore.singularize] || class_name.reflections[model.to_s.underscore.pluralize]
15
- case inverse_reflection&.source_reflection&.class&.to_s&.split("::")&.last
16
- when "HasOneReflection"
17
- table_name = model.to_s.underscore.to_sym
18
- when "HasManyReflection"
19
- table_name = model.to_s.underscore.pluralize.to_sym
20
- else
21
- raise AssociationMissingError.new missing_in: class_name, association: model.to_s.underscore.pluralize
22
- end
12
+ table_name = table_name class_name
23
13
 
24
14
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
25
15
  scope association.pluralize, -> do
@@ -36,6 +26,27 @@ module AssociationScope
36
26
  end
37
27
  RUBY
38
28
  end
29
+
30
+ private
31
+
32
+ def table_name(class_name)
33
+ case inverse_reflection(class_name)&.source_reflection&.class&.to_s&.split("::")&.last
34
+ when "HasOneReflection"
35
+ model.to_s.underscore.to_sym
36
+ when "HasManyReflection"
37
+ model.to_s.underscore.pluralize.to_sym
38
+ else
39
+ raise AssociationMissingError.new missing_in: class_name, association: model.to_s.underscore.pluralize
40
+ end
41
+ end
42
+
43
+ def inverse_reflection(class_name)
44
+ class_name.reflections[model.to_s.underscore.singularize] || class_name.reflections[model.to_s.underscore.pluralize]
45
+ end
46
+
47
+ def reflection_details
48
+ model.reflections[association]
49
+ end
39
50
  end
40
51
  end
41
52
  end
@@ -5,13 +5,12 @@ module AssociationScope
5
5
  class HasAndBelongsToManyReflection < Scope
6
6
  def apply
7
7
  association = @association.pluralize
8
- details = model.reflections[association]
9
- class_name = details.options[:class_name]&.constantize || association.singularize.camelize.constantize
8
+ class_name = reflection_details.options[:class_name]&.constantize || association.singularize.camelize.constantize
10
9
  table_name = model.to_s.underscore.pluralize.to_sym
11
10
 
12
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
13
- raise AssociationMissingError.new(missing_in: class_name, association: table_name) unless class_name.reflections.has_key?(table_name.to_s)
11
+ raise AssociationMissingError.new(missing_in: class_name, association: table_name) unless class_name.reflections.has_key?(table_name.to_s)
14
12
 
13
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
14
  scope association, -> do
16
15
  class_name
17
16
  .joins(table_name)
@@ -20,6 +19,12 @@ module AssociationScope
20
19
  end
21
20
  RUBY
22
21
  end
22
+
23
+ private
24
+
25
+ def reflection_details
26
+ model.reflections[association]
27
+ end
23
28
  end
24
29
  end
25
30
  end
@@ -4,14 +4,14 @@ module AssociationScope
4
4
  class Scope
5
5
  class HasManyReflection < Scope
6
6
  def apply
7
- details = model.reflections[@association]
8
- class_name = details.options[:class_name]&.constantize || association.singularize.camelize.constantize
7
+ class_name = reflection_details.options[:class_name]&.constantize || association.singularize.camelize.constantize
8
+
9
9
  association = @association.pluralize
10
10
  column_name = model.to_s.underscore
11
11
 
12
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
13
- raise AssociationMissingError.new(missing_in: class_name, association: column_name) unless class_name.reflections.has_key?(column_name)
12
+ raise AssociationMissingError.new(missing_in: class_name, association: column_name) unless class_name.reflections.has_key?(column_name)
14
13
 
14
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
15
  scope association, -> do
16
16
  class_name
17
17
  .where(column_name => self)
@@ -19,6 +19,12 @@ module AssociationScope
19
19
  end
20
20
  RUBY
21
21
  end
22
+
23
+ private
24
+
25
+ def reflection_details
26
+ model.reflections[@association]
27
+ end
22
28
  end
23
29
  end
24
30
  end
@@ -3,6 +3,7 @@
3
3
  module AssociationScope
4
4
  class Scope
5
5
  class HasOneReflection < HasManyReflection
6
+ # works the same way like has_many reflections
6
7
  end
7
8
  end
8
9
  end
@@ -4,24 +4,14 @@ module AssociationScope
4
4
  class Scope
5
5
  class ThroughReflection < Scope
6
6
  def apply
7
- details = model.reflections[@association]
8
7
  association = @association
9
- class_name = details.options[:class_name]&.constantize || association.singularize.camelize.constantize
8
+ class_name = reflection_details.options[:class_name]&.constantize || association.singularize.camelize.constantize
9
+ first_join = inverse_reflection(class_name)&.options&.fetch(:through, nil) || inverse_reflection(class_name)&.options&.fetch(:source, nil)
10
+ second_join = compute_second_join class_name
10
11
 
11
- inverse = details.options[:inverse_of]&.to_s || model.to_s.underscore
12
- inverse_reflection = class_name.reflections[inverse.singularize] || class_name.reflections[inverse.pluralize]
13
-
14
- first_join = inverse_reflection&.options&.fetch(:through, nil) || inverse_reflection&.options&.fetch(:source, nil)
15
-
16
- reflection_type = inverse_reflection&.source_reflection&.class&.to_s&.split("::")&.last
17
- second_join = if %w[HasOneReflection BelongsToReflection].include?(reflection_type)
18
- model.to_s.underscore.to_sym
19
- else
20
- model.to_s.underscore.pluralize.to_sym
21
- end
12
+ raise AssociationMissingError.new missing_in: class_name, association: inverse unless inverse_reflection(class_name)
22
13
 
23
14
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
24
- raise AssociationMissingError.new missing_in: class_name, association: inverse unless inverse_reflection
25
15
  scope association.pluralize, -> do
26
16
  class_name
27
17
  .joins(first_join => second_join)
@@ -29,6 +19,32 @@ module AssociationScope
29
19
  end
30
20
  RUBY
31
21
  end
22
+
23
+ private
24
+
25
+ def reflection_details
26
+ model.reflections[association]
27
+ end
28
+
29
+ def inverse
30
+ reflection_details.options[:inverse_of]&.to_s || model.to_s.underscore
31
+ end
32
+
33
+ def inverse_reflection class_name
34
+ class_name.reflections[inverse.singularize] || class_name.reflections[inverse.pluralize]
35
+ end
36
+
37
+ def reflection_type class_name
38
+ inverse_reflection(class_name)&.source_reflection&.class&.to_s&.split("::")&.last
39
+ end
40
+
41
+ def compute_second_join class_name
42
+ if %w[HasOneReflection BelongsToReflection].include?(reflection_type class_name)
43
+ model.to_s.underscore.to_sym
44
+ else
45
+ model.to_s.underscore.pluralize.to_sym
46
+ end
47
+ end
32
48
  end
33
49
  end
34
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AssociationScope
4
- VERSION = "0.3.2"
4
+ VERSION = "0.3.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: association_scope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - datae
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-07 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -100,14 +100,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 2.6.8
104
104
  required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: '0'
109
109
  requirements: []
110
- rubygems_version: 3.1.4
110
+ rubygems_version: 3.2.9
111
111
  signing_key:
112
112
  specification_version: 4
113
113
  summary: AssociationScope adds useful scopes targeting Associations in ActiveRecord.