association_scope 0.4.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67d2f037f4c3007105757fe5b90f5307eb56614979e7cd4fa83d9036b5584321
4
- data.tar.gz: d775072058420799584cf18dc27d80c246070dfd2ae1246e084f0a25acf3aa44
3
+ metadata.gz: '0059e9dbe18df446d6d2e2052bfac18e55a2a63bc80cc3fdb8b1b7c1857de712'
4
+ data.tar.gz: 1cb46137b1e72f91cf131aa03961566deee85425e231cf68c9d8b47db4acdcdb
5
5
  SHA512:
6
- metadata.gz: 5aa81882d47e6207b82deb659f43f3010e83d985fe1bed9a411e29c5796082509c4d19f4435bfdbb9d8a636878c06ac3dde49e7543bf5f7b7db38ec4583d0504
7
- data.tar.gz: 22d3f940c21d6e1722eef994d0294a80d6e3f80a87a3bbadba1f457f1eeb6ef54fecc6ef3c9d761100213dcdc669f04c5f242cc8e95f4546151639f15727eb25
6
+ metadata.gz: ad2173c80fc92258f0c559c5a4fd6314ed3c7fafe8ea1f9c50824df7434d8c130a828e3d2575786d31558d6d6f11b0b2583506f463d5283807e1d1f12ff13f81
7
+ data.tar.gz: 8ade7d8c45150524d87740fe69759199f0263054cc6184e1a93a5fba14acd5654df02d9967d1761b864b540d09be93aabd90b910a4c39b86b9664cbb16c3ed8e
data/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ ## 1.0.0 - 2026-09-10
6
+
7
+ ### Changed
8
+
9
+ - Support is now limited to Ruby 3.2 through 4.0 and Rails 7.1 or newer.
10
+ - The development and test dependencies are pinned and the CI suite explicitly
11
+ tests the supported Ruby, Rails, and database adapter versions (SQLite and
12
+ PostgreSQL).
13
+
14
+ ### Fixed
15
+
16
+ - Preserve scoped `belongs_to`, through, and HABTM association predicates.
17
+ - Support explicit source selections and self-referential `belongs_to` scopes.
18
+ - Honor custom association primary keys for direct associations.
19
+ - Return one record per owner for `has_one :through`, preserving source order
20
+ and applying offsets per owner for both direct and through `has_one` scopes.
21
+ - Exercise real queries and chaining in the installed-gem smoke test.
22
+
23
+ ### Documentation
24
+
25
+ - Documented inverse-association requirements, generated scope naming,
26
+ unsupported options, upgrade notes, and verification commands.
27
+
28
+ ### Upgrade notes
29
+
30
+ - Upgrade to Ruby 3.2 or newer and Rails 7.1 or newer before updating the gem.
31
+ - Replace polymorphic `belongs_to` association scopes with explicit application
32
+ scopes; they are not supported.
33
+ - Association scopes now require the corresponding inverse association on the
34
+ target model. Add `inverse_of` when Rails cannot infer that association.
35
+ - `has_association_scope_on` accepts only an association name or an array of
36
+ association names. It does not accept `only:` or `except:` options.
37
+
38
+ ## 0.4.0 - 2021-11-12
39
+
40
+ ### Added
41
+
42
+ - Polymorphic association behavior and test coverage.
43
+
44
+ ## 0.3.3 - 2021-11-12
45
+
46
+ ### Changed
47
+
48
+ - Updated development dependencies and CI configuration.
49
+
50
+ ## 0.3.0
51
+
52
+ See the [v0.3.0 release](https://github.com/datae95/association_scope/tree/v0.3.0)
53
+ for the changes in this release.
data/README.md CHANGED
@@ -57,6 +57,40 @@ Topic.all.users
57
57
  ```
58
58
  to retrieve the users of all of the topics of your application.
59
59
 
60
+ The argument must be an array of association names.
61
+ Each generated relation scope uses the pluralized association name: `:user`
62
+ creates `.users`, and `:profile` creates `.profiles`. Names must be unique
63
+ after pluralization and must not already be defined as class methods/scopes.
64
+ There is no `only:` or `except:` option; list exactly the associations to
65
+ expose.
66
+
67
+ ### Inverse associations
68
+
69
+ The association must have a matching inverse association on its target model.
70
+ AssociationScope uses that inverse to construct the join. Define both sides
71
+ before calling `has_association_scope_on`, and use `inverse_of` when the inverse
72
+ cannot be inferred (for example, with a custom `class_name` or `source`):
73
+
74
+ ```ruby
75
+ class Topic < ApplicationRecord
76
+ belongs_to :user, inverse_of: :topics
77
+ has_association_scope_on [:user]
78
+ end
79
+
80
+ class User < ApplicationRecord
81
+ has_many :topics, inverse_of: :user
82
+ end
83
+ ```
84
+
85
+ ### Supported association types
86
+
87
+ `has_association_scope_on` supports `belongs_to`, `has_one`, `has_many`,
88
+ `has_many :through`, `has_one :through`, and `has_and_belongs_to_many`
89
+ associations. Polymorphic `has_many` associations (for example,
90
+ `has_many :pictures, as: :imageable`) are supported. A polymorphic
91
+ `belongs_to` association is not supported because its target model cannot be
92
+ determined when the scope is defined.
93
+
60
94
  ### Migration from `.of_model`
61
95
  When you already use any form of `.of_model` scope, you can replace it with association scopes:
62
96
 
@@ -74,8 +108,8 @@ scope.of_users(users)
74
108
  users.topics.merge(scope)
75
109
  ```
76
110
 
77
- ## Known Issues
78
- * This gem works with `reflections`.
111
+ ## Limitations
112
+ * This gem works with Active Record `reflections`.
79
113
  To make this work, the `has_association_scope_on` call has to be below your association definitions.
80
114
  ```ruby
81
115
  # won't work
@@ -95,9 +129,40 @@ end
95
129
  Workaround: Migrate JSON columns to JSONB.
96
130
  * Error messages are not raised during application start, but on first instantiation, because of the order in which classes are loaded.
97
131
 
132
+ ## Compatibility
133
+
134
+ The gem supports Ruby 3.2 through 4.0 and Rails 7.1 or newer. The CI matrix
135
+ tests Rails 7.1, 7.2, 8.0, and 8.1 on each supported Ruby version, using both
136
+ SQLite and PostgreSQL.
137
+
138
+ The test suite supports SQLite and PostgreSQL. PostgreSQL is recommended when
139
+ using `distinct` with JSON-valued columns; SQLite does not provide the same
140
+ JSON type behavior.
141
+
142
+ ### Upgrade notes
143
+
144
+ Version 1.0 drops support for Ruby versions before 3.2 and Rails versions
145
+ before 7.1. Upgrade Ruby and Rails first, then run `bundle update
146
+ association_scope`. If you previously relied on a polymorphic `belongs_to`
147
+ association scope, replace it with an explicit application scope; that
148
+ association type is intentionally rejected. Also ensure every exposed
149
+ association has an inverse on its target model and remove unsupported
150
+ `only:`/`except:` arguments.
151
+
98
152
  ## Development
99
153
  Clone this repository and run `bundle`.
154
+
155
+ The development Ruby version is 3.4.7. See [Compatibility](#compatibility) for
156
+ the supported runtime versions.
157
+
100
158
  To use `rails console` you have to navigate to the dummy application
101
159
  ```bash
102
160
  $ cd spec/dummy
103
161
  ```
162
+
163
+ ### Verification
164
+
165
+ Run the test suite with `bundle exec rake` (or `bundle exec rspec`). Check
166
+ formatting with `bundle exec standardrb` and dependencies with
167
+ `bundle exec bundler-audit check --update`. The CI matrix additionally runs
168
+ the suite on the supported Ruby/Rails combinations with SQLite and PostgreSQL.
data/Rakefile CHANGED
@@ -4,12 +4,11 @@ require "bundler/setup"
4
4
 
5
5
  require "bundler/gem_tasks"
6
6
 
7
- require "rake/testtask"
7
+ require "rspec/core/rake_task"
8
8
 
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << "test"
11
- t.pattern = "test/**/*_test.rb"
9
+ RSpec::Core::RakeTask.new(:spec) do |t|
10
+ t.pattern = "spec/**/*_spec.rb"
12
11
  t.verbose = false
13
12
  end
14
13
 
15
- task default: :test
14
+ task default: :spec
@@ -9,43 +9,34 @@ module AssociationScope
9
9
  end
10
10
 
11
11
  association = @association
12
- class_name = reflection_details.options[:class_name]&.constantize || association.camelize.constantize
13
- foreign_key = reflection_details.options[:foreign_key]
14
- association_name = association.to_s.underscore.to_sym
15
- own_table_name = class_name.to_s.pluralize.underscore
16
- table_name = table_name class_name
17
-
18
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
19
- scope association.pluralize, -> do
20
- if foreign_key.present?
21
- class_name
22
- .joins("JOIN #{table_name} ON #{table_name}.#{foreign_key} = #{own_table_name}.id")
23
- else
24
- class_name
25
- .joins(table_name)
26
- end
27
- .where(table_name => { association_name =>
28
- select("#{association_name}_id".to_sym) })
29
- .distinct
30
- end
31
- RUBY
32
- end
33
-
34
- private
12
+ class_name = reflection_details.klass
13
+ inverse_association = inverse_reflection(class_name)
35
14
 
36
- def table_name(class_name)
37
- case inverse_reflection(class_name)&.source_reflection&.class&.to_s&.split("::")&.last
38
- when "HasOneReflection"
39
- model.to_s.underscore.to_sym
40
- when "HasManyReflection"
41
- model.to_s.underscore.pluralize.to_sym
42
- else
15
+ unless inverse_association
43
16
  raise AssociationMissingError.new missing_in: class_name, association: model.to_s.underscore.pluralize
44
17
  end
18
+
19
+ foreign_key = reflection_details.foreign_key
20
+ validate_scope!(reflection_details)
21
+ association_scope = reflection_details.scope
22
+ owner_key = model.arel_table[foreign_key]
23
+ target_key = class_name.arel_table[reflection_details.association_primary_key]
24
+
25
+ model.scope association.pluralize, -> do
26
+ Scope.target_relation(class_name, association_scope)
27
+ .where(target_key.in(reselect(owner_key).arel))
28
+ .distinct
29
+ end
45
30
  end
46
31
 
32
+ private
33
+
47
34
  def inverse_reflection(class_name)
48
- class_name.reflections[model.to_s.underscore.singularize] || class_name.reflections[model.to_s.underscore.pluralize]
35
+ inverse_name = reflection_details.options[:inverse_of]
36
+
37
+ class_name.reflections[inverse_name.to_s] ||
38
+ class_name.reflections[model.to_s.underscore.singularize] ||
39
+ class_name.reflections[model.to_s.underscore.pluralize]
49
40
  end
50
41
 
51
42
  def reflection_details
@@ -5,19 +5,20 @@ module AssociationScope
5
5
  class HasAndBelongsToManyReflection < Scope
6
6
  def apply
7
7
  association = @association.pluralize
8
- class_name = reflection_details.options[:class_name]&.constantize || association.singularize.camelize.constantize
9
- table_name = model.to_s.underscore.pluralize.to_sym
8
+ class_name = reflection_details.klass
9
+ inverse_association = inverse_association(class_name)
10
+ validate_scope!(reflection_details)
11
+ association_scope = reflection_details.scope
12
+ owner_table = model.table_name
10
13
 
11
- raise AssociationMissingError.new(missing_in: class_name, association: table_name) unless class_name.reflections.has_key?(table_name.to_s)
14
+ raise AssociationMissingError.new(missing_in: class_name, association: model.table_name) unless inverse_association
12
15
 
13
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
- scope association, -> do
15
- class_name
16
- .joins(table_name)
17
- .where(table_name => self)
18
- .distinct
19
- end
20
- RUBY
16
+ model.scope association, -> do
17
+ Scope.target_relation(class_name, association_scope)
18
+ .joins(inverse_association)
19
+ .where(owner_table => self)
20
+ .distinct
21
+ end
21
22
  end
22
23
 
23
24
  private
@@ -25,6 +26,14 @@ module AssociationScope
25
26
  def reflection_details
26
27
  model.reflections[association]
27
28
  end
29
+
30
+ def inverse_association(class_name)
31
+ class_name.reflections.values.find do |reflection|
32
+ reflection.macro == :has_and_belongs_to_many &&
33
+ reflection.klass == model &&
34
+ reflection.join_table == reflection_details.join_table
35
+ end&.name
36
+ end
28
37
  end
29
38
  end
30
39
  end
@@ -4,20 +4,30 @@ module AssociationScope
4
4
  class Scope
5
5
  class HasManyReflection < Scope
6
6
  def apply
7
- class_name = reflection_details.options[:class_name]&.constantize || association.singularize.camelize.constantize
7
+ class_name = reflection_details.klass
8
8
 
9
9
  association = @association.pluralize
10
10
  column_name = reflection_details.options[:as] || model.to_s.underscore
11
+ inverse_association = inverse_reflection(class_name, column_name)
11
12
 
12
- raise AssociationMissingError.new(missing_in: class_name, association: column_name) unless class_name.reflections.has_key?(column_name.to_s)
13
+ raise AssociationMissingError.new(missing_in: class_name, association: column_name) unless inverse_association
13
14
 
14
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
- scope association, -> do
16
- class_name
17
- .where(column_name => self)
18
- .distinct
19
- end
20
- RUBY
15
+ association_scope = reflection_details.scope
16
+ validate_scope!(reflection_details)
17
+ polymorphic = reflection_details.options[:as]
18
+ foreign_key = reflection_details.foreign_key
19
+ owner_key = model.arel_table[reflection_details.active_record_primary_key]
20
+ target_key = class_name.arel_table[foreign_key]
21
+ foreign_type = reflection_details.type if polymorphic
22
+ owner_type = model.polymorphic_name if polymorphic
23
+ singular = reflection_details.macro == :has_one
24
+
25
+ model.scope association, -> do
26
+ relation = Scope.target_relation(class_name, association_scope)
27
+ .where(target_key.in(reselect(owner_key).arel))
28
+ relation = relation.where(foreign_type => owner_type) if polymorphic
29
+ singular ? Scope.one_per_owner(relation, target_key) : relation.distinct
30
+ end
21
31
  end
22
32
 
23
33
  private
@@ -25,6 +35,12 @@ module AssociationScope
25
35
  def reflection_details
26
36
  model.reflections[@association]
27
37
  end
38
+
39
+ def inverse_reflection(class_name, column_name)
40
+ inverse_name = reflection_details.options[:inverse_of]
41
+
42
+ class_name.reflections[inverse_name.to_s] || class_name.reflections[column_name.to_s]
43
+ end
28
44
  end
29
45
  end
30
46
  end
@@ -5,19 +5,49 @@ module AssociationScope
5
5
  class ThroughReflection < Scope
6
6
  def apply
7
7
  association = @association
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
8
+ class_name = begin
9
+ reflection_details.klass
10
+ rescue ActiveRecord::AmbiguousSourceReflectionForThroughAssociation
11
+ # Rails cannot resolve an omitted source when multiple source
12
+ # reflections exist; retain the historical association-name
13
+ # fallback for this inherently ambiguous case.
14
+ association.singularize.camelize.constantize
15
+ end
16
+ source = begin
17
+ reflection_details.source_reflection
18
+ rescue ActiveRecord::AmbiguousSourceReflectionForThroughAssociation
19
+ nil
20
+ end
21
+ validate_scope!(reflection_details)
22
+ source ||= reflection_details.through_reflection.klass.reflections.values.find do |candidate|
23
+ candidate.name.to_s == association.to_s && candidate.klass == class_name && candidate.through_reflection?
24
+ end
25
+ if source&.through_reflection?
26
+ first_join = source.options[:through]
27
+ second_join = reflection_details.options[:through].to_sym
28
+ else
29
+ first_join = inverse_reflection(class_name)&.options&.fetch(:through, nil) || inverse_reflection(class_name)&.options&.fetch(:source, nil)
30
+ second_join = compute_second_join class_name
31
+ end
11
32
 
12
33
  raise AssociationMissingError.new missing_in: class_name, association: inverse unless inverse_reflection(class_name)
34
+ through_reflection = reflection_details.through_reflection
35
+ through_table = through_reflection.klass.table_name
36
+ through_key = through_reflection.belongs_to? ? through_reflection.association_primary_key : through_reflection.foreign_key
37
+ source_key = through_reflection.belongs_to? ? through_reflection.foreign_key : through_reflection.active_record_primary_key
38
+ owner_key = model.arel_table[source_key]
39
+ partition_key = through_reflection.klass.arel_table[through_key]
40
+ association_scope = reflection_details.scope
41
+ source_scope = source&.scope
42
+ validate_scope!(source) if source
43
+ singular = reflection_details.macro == :has_one
13
44
 
14
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
- scope association.pluralize, -> do
16
- class_name
17
- .joins(first_join => second_join)
18
- .distinct
19
- end
20
- RUBY
45
+ model.scope association.pluralize, -> do
46
+ relation = Scope.target_relation(class_name, source_scope, association_scope)
47
+ .joins(first_join => second_join)
48
+ .where(through_table => {through_key => reselect(owner_key)})
49
+ singular ? Scope.one_per_owner(relation, partition_key) : relation.distinct
50
+ end
21
51
  end
22
52
 
23
53
  private
@@ -10,11 +10,58 @@ module AssociationScope
10
10
  end
11
11
 
12
12
  def self.inject_scopes(model, reflections)
13
+ unknown_association = reflections.find { |association| !model.reflections.key?(association) }
14
+ if unknown_association
15
+ raise AssociationMissingError.new(missing_in: model, association: unknown_association)
16
+ end
17
+
18
+ generated_scopes = reflections.map(&:pluralize)
19
+ if generated_scopes.uniq.length != generated_scopes.length
20
+ raise ArgumentError, "association scope names must be unique after pluralization"
21
+ end
22
+
23
+ generated_scopes.each do |scope_name|
24
+ if model.respond_to?(scope_name)
25
+ raise ArgumentError, "association scope :#{scope_name} is already defined on #{model}"
26
+ end
27
+ end
28
+
13
29
  model.reflections.slice(*reflections).each do |association, details|
14
30
  scope_type = details.class.to_s.split("::").last
31
+ scope_type = "HasManyReflection" if scope_type == "HasOneReflection"
15
32
 
16
33
  "AssociationScope::Scope::#{scope_type}".constantize.new(model, association).apply
17
34
  end
18
35
  end
36
+
37
+ def self.target_relation(klass, *scopes)
38
+ # Start independently of the owners' current scope, including for self joins.
39
+ scopes.compact.reduce(klass.default_scoped) do |relation, scope|
40
+ relation.instance_exec(&scope) || relation
41
+ end
42
+ end
43
+
44
+ def self.one_per_owner(relation, owner_key)
45
+ klass = relation.klass
46
+ table = klass.arel_table
47
+ orders = relation.arel.orders.presence || [table[klass.primary_key].asc]
48
+ window = Arel::Nodes::Window.new.partition(owner_key).order(*orders)
49
+ row_number = Arel::Nodes::NamedFunction.new("ROW_NUMBER", []).over(window)
50
+ ranked = relation.except(:select, :order, :limit, :offset, :distinct)
51
+ .select(table[Arel.star], row_number.as("association_scope_row_number"))
52
+
53
+ # Keep ordering inside the window so offsets select a record for each owner.
54
+ result = klass.unscoped.from(ranked, klass.table_name)
55
+ .where(table[:association_scope_row_number].eq(relation.offset_value.to_i + 1))
56
+ .distinct
57
+ relation.select_values.any? ? result.select(*relation.select_values) : result
58
+ end
59
+
60
+ private
61
+
62
+ def validate_scope!(reflection)
63
+ scope = reflection.scope
64
+ raise ArgumentError, "owner-dependent association scopes are not supported" if scope && scope.arity != 0
65
+ end
19
66
  end
20
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AssociationScope
4
- VERSION = "0.4.0"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -3,7 +3,6 @@
3
3
  require "association_scope/version"
4
4
  require "association_scope/scope"
5
5
  require "association_scope/scope/has_many_reflection"
6
- require "association_scope/scope/has_one_reflection"
7
6
  require "association_scope/scope/belongs_to_reflection"
8
7
  require "association_scope/scope/has_and_belongs_to_many_reflection"
9
8
  require "association_scope/scope/through_reflection"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: association_scope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - datae
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-11-12 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -16,56 +15,56 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '5'
18
+ version: '7.1'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '5'
25
+ version: '7.1'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: standard
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: 1.1.6
32
+ version: '1.56'
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: 1.1.6
39
+ version: '1.56'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: yard
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - "~>"
46
45
  - !ruby/object:Gem::Version
47
- version: 0.9.26
46
+ version: 0.9.37
48
47
  type: :development
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - "~>"
53
52
  - !ruby/object:Gem::Version
54
- version: 0.9.26
53
+ version: 0.9.37
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: rspec
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
58
  - - "~>"
60
59
  - !ruby/object:Gem::Version
61
- version: '3.10'
60
+ version: '3.13'
62
61
  type: :development
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - "~>"
67
66
  - !ruby/object:Gem::Version
68
- version: '3.10'
67
+ version: '3.13'
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: awesome_print
71
70
  requirement: !ruby/object:Gem::Requirement
@@ -80,13 +79,29 @@ dependencies:
80
79
  - - "~>"
81
80
  - !ruby/object:Gem::Version
82
81
  version: 1.9.2
83
- description: AssociationScope adds useful scopes targeting Associations in ActiveRecord.
82
+ - !ruby/object:Gem::Dependency
83
+ name: bundler-audit
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.9'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
96
+ description: AssociationScope lets Active Record relations expose associations as
97
+ chainable scopes.
84
98
  email:
85
99
  - accounts@datae.de
86
100
  executables: []
87
101
  extensions: []
88
102
  extra_rdoc_files: []
89
103
  files:
104
+ - CHANGELOG.md
90
105
  - MIT-LICENSE
91
106
  - README.md
92
107
  - Rakefile
@@ -97,17 +112,15 @@ files:
97
112
  - lib/association_scope/scope/belongs_to_reflection.rb
98
113
  - lib/association_scope/scope/has_and_belongs_to_many_reflection.rb
99
114
  - lib/association_scope/scope/has_many_reflection.rb
100
- - lib/association_scope/scope/has_one_reflection.rb
101
115
  - lib/association_scope/scope/through_reflection.rb
102
116
  - lib/association_scope/version.rb
103
117
  homepage: https://github.com/datae95/association_scope
104
118
  licenses:
105
119
  - MIT
106
120
  metadata:
107
- homepage_uri: https://github.com/datae95/association_scope
121
+ homepage_uri: https://github.com/datae95/association_scope#readme
108
122
  source_code_uri: https://github.com/datae95/association_scope
109
- changelog_uri: https://github.com/datae95/association_scope/changelog
110
- post_install_message:
123
+ changelog_uri: https://github.com/datae95/association_scope/blob/main/CHANGELOG.md
111
124
  rdoc_options: []
112
125
  require_paths:
113
126
  - lib
@@ -115,15 +128,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
128
  requirements:
116
129
  - - ">="
117
130
  - !ruby/object:Gem::Version
118
- version: 2.6.8
131
+ version: '3.2'
132
+ - - "<"
133
+ - !ruby/object:Gem::Version
134
+ version: '4.1'
119
135
  required_rubygems_version: !ruby/object:Gem::Requirement
120
136
  requirements:
121
137
  - - ">="
122
138
  - !ruby/object:Gem::Version
123
139
  version: '0'
124
140
  requirements: []
125
- rubygems_version: 3.2.25
126
- signing_key:
141
+ rubygems_version: 4.0.16
127
142
  specification_version: 4
128
- summary: AssociationScope adds useful scopes targeting Associations in ActiveRecord.
143
+ summary: Chain Active Record associations from relation scopes.
129
144
  test_files: []
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AssociationScope
4
- class Scope
5
- class HasOneReflection < HasManyReflection
6
- # works the same way like has_many reflections
7
- end
8
- end
9
- end