Skip to content

Commit

Permalink
Fix detection of relationships when there are multiple associations b…
Browse files Browse the repository at this point in the history
…etween users and companies
  • Loading branch information
benedikt committed Mar 13, 2024
1 parent baa3cf2 commit 1700bab
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANEGLOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Userlist for Ruby on Rails Changelog

## Unreleased (main)

- Fix detection of relationships when there are multiple associations between users and companies

## v0.6.2 (2023-11-30)

- Upgrades dependencies
Expand Down
11 changes: 10 additions & 1 deletion lib/userlist/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ module Rails
:userlist_user
].freeze

REFLECTION_PRIORITY = [
ActiveRecord::Reflection::ThroughReflection,
ActiveRecord::Reflection::HasManyReflection,
ActiveRecord::Reflection::HasOneReflection
].freeze

def self.with_current_user(user)
Thread.current[:userlist_current_user] = user
yield
Expand Down Expand Up @@ -56,7 +62,10 @@ def self.detect_relationship(from, to)
def self.find_reflection(from, to)
return unless from && to

from.reflect_on_all_associations.find { |r| r.class_name == to.to_s }
from
.reflect_on_all_associations
.sort_by { |r| REFLECTION_PRIORITY.index(r.class) || REFLECTION_PRIORITY.length }
.find { |r| r.class_name == to.to_s }
end

def self.find_association_between(from, to)
Expand Down
22 changes: 22 additions & 0 deletions spec/support/dummies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,25 @@ class Company < ActiveRecord::Base
has_one :user, class_name: 'HasOneUser::User'
end
end

module MultipleRelationships
class User < ActiveRecord::Base
has_many :memberships, class_name: 'MultipleRelationships::Membership'
has_many :companies, through: :memberships, class_name: 'MultipleRelationships::Company'

has_many :direct_companies, class_name: 'MultipleRelationships::Company'
has_one :company, class_name: 'MultipleRelationships::Company'
end

class Company < ActiveRecord::Base
has_many :direct_users, class_name: 'MultipleRelationships::User'

has_many :memberships, class_name: 'MultipleRelationships::Membership'
has_many :users, through: :memberships, class_name: 'MultipleRelationships::User'
end

class Membership < ActiveRecord::Base
belongs_to :user, class_name: 'MultipleRelationships::User'
belongs_to :company, class_name: 'MultipleRelationships::Company'
end
end
24 changes: 19 additions & 5 deletions spec/userlist/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
context 'when it is a has many through relationship' do
let(:scope) { HasManyThrough }

it 'should detect the relationship model between to other models' do
it 'should detect the relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(scope::Membership)
end
Expand All @@ -77,7 +77,7 @@
context 'when it is a has and belongs to many relationship' do
let(:scope) { HasAndBelongsToMany }

it 'should not detect a relationship model between to other models' do
it 'should not detect a relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(nil)
end
Expand All @@ -86,7 +86,7 @@
context 'when it is a has many relationship' do
let(:scope) { HasManyCompanies }

it 'should not detect a relationship model between to other models' do
it 'should not detect a relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(nil)
end
Expand All @@ -95,7 +95,7 @@
context 'when it is a has one relationship' do
let(:scope) { HasOneCompany }

it 'should not detect a relationship model between to other models' do
it 'should not detect a relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(nil)
end
Expand All @@ -104,10 +104,24 @@
context 'when it is a belongs to relationship' do
let(:scope) { HasManyUsers }

it 'should not detect a relationship model between to other models' do
it 'should not detect a relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(nil)
end
end

context 'when there are multiple relationships' do
let(:scope) { MultipleRelationships }

it 'should detect the relationship model between two other models' do
relationship = described_class.detect_relationship(scope::User, scope::Company)
expect(relationship).to eq(scope::Membership)
end

it 'should detect the relationship model between two other models in reverse order' do
relationship = described_class.detect_relationship(scope::Company, scope::User)
expect(relationship).to eq(scope::Membership)
end
end
end
end

0 comments on commit 1700bab

Please sign in to comment.