hyperstack-org / hyperstack-org/hyperstack

hyper-model incorrectly loads/instantiates through association

Offen
#225 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
JavaScript
Sterne
538
Forks
41
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

When a (kind of) complex through association is present, and you call the association without the through records loaded, hyper-model will incorrectly load them

```ruby
class User < ApplicationRecord
has_many :organization_memberships,
dependent: :destroy,
inverse_of: :user
has_many :organizations,
class_name: 'Organization',
inverse_of: :members,
source: :organization,
through: :organization_memberships
end

class Organization < ApplicationRecord
has_many :memberships,
-> { includes(:user).order('users.nickname ASC').references(:user) },
class_name: 'OrganizationMembership',
dependent: :destroy,
inverse_of: :organization
has_many :members,
-> { order('users.nickname ASC') },
class_name: 'User',
inverse_of: :organizations,
source: :user,
through: :memberships
end

class OrganizationMembership < ApplicationRecord
belongs_to :organization, inverse_of: :memberships
belongs_to :user, inverse_of: :organization_memberships
end
```

And then requesting any data from an organization through user will cause it to improperly instantiate the through association, causing the inverse the be totally busted

```ruby
render do
User.first.organizations.each do |organization|
organization.name
end
end
```

Will cause this to happen

```ruby
Organization.first.members.target_klass
# => Organization
```
It should be User. And while the association still kind of works, it breaks when you try to do any sort of scoping on that association.

The problem happens when it sets up the through association, it mistakenly sets both the owner and target_klass to Organization.

This is the code where I found the problem:

```ruby
module ActiveRecord
module Associations
class AssociationReflection
def add_member(member, owner)
owner.attributes[attribute] ||= ReactiveRecord::Collection.new(owner_class, owner, self)
owner.attributes[attribute]._internal_push member
end
end
end
end
```

I'm not sure if the association reflection set up is just already busted, but changing owner_class to member.class seems to fix the issue

```ruby
module ActiveRecord
module Associations
class AssociationReflection
def add_member(member, owner)
owner.attributes[attribute] ||= ReactiveRecord::Collection.new(member.class, owner, self)
owner.attributes[attribute]._internal_push member
end
end
end
end
```

The other interesting thing, is if you call the association the other way around `Organization.first.members` it seems to properly set things up first, and then it is never broken.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.