Skip to content
This repository was archived by the owner on Jan 5, 2022. It is now read-only.

Commit ce5f6d9

Browse files
committed
Add support for associations with inverse_of option
Relations may have custom names which do not match with model class name. ActiveRecord provides :inverse_of option for association definition to support that.
1 parent e498eed commit ce5f6d9

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

lib/cache_depends_on/association_cache_dependency_definer.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ def find_inverse_of(association)
3232
end
3333

3434
def find_singular_inverse_of(association)
35-
suggested_singular_reverse_association_name = model_klass.model_name.singular.to_sym
35+
suggested_singular_reverse_association_name = association.options.fetch(:inverse_of, model_klass.model_name.singular.to_sym)
3636
association.klass.reflect_on_association suggested_singular_reverse_association_name
3737
end
3838

3939
def find_plural_inverse_of(association)
40-
suggested_plural_reverse_association_name = model_klass.model_name.plural.to_sym
40+
suggested_plural_reverse_association_name = association.options.fetch(:inverse_of, model_klass.model_name.plural.to_sym)
4141
association.klass.reflect_on_association suggested_plural_reverse_association_name
4242
end
4343

spec/cache_depends_on_spec.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,73 @@ def another_after_cache_invalidation_hook; end
366366
provider.touch
367367
end
368368
end
369+
370+
describe 'associations with inverse_of option' do
371+
class CompanyAddress < ActiveRecord::Base
372+
belongs_to :company, inverse_of: :address
373+
has_many :company_employees, through: :company, source: :employees
374+
end
375+
376+
class Company < ActiveRecord::Base
377+
has_many :employees, class_name: 'User'
378+
has_one :address, class_name: 'CompanyAddress', inverse_of: :company
379+
end
380+
381+
class UserProfile < ActiveRecord::Base
382+
belongs_to :user, inverse_of: :profile
383+
end
384+
385+
class UserRole < ActiveRecord::Base
386+
belongs_to :user, inverse_of: :roles
387+
end
388+
389+
class User < ActiveRecord::Base
390+
belongs_to :company, inverse_of: :employees
391+
has_many :roles, class_name: 'UserRole'
392+
has_one :profile, class_name: 'UserProfile'
393+
has_one :company_address, through: :company, source: :address, inverse_of: :company_employees
394+
395+
cache_depends_on :roles, :profile, :company, :company_address
396+
end
397+
398+
let!(:company) { Company.create! }
399+
let!(:company_address) { CompanyAddress.create! company: company }
400+
let!(:user) { User.create! company: company }
401+
let!(:user_profile) { UserProfile.create! user: user }
402+
let!(:user_role) { UserRole.create! user: user }
403+
404+
before { user.update_column(:updated_at, 1.day.ago) }
405+
406+
shared_examples 'dependent entity updating' do
407+
let(:dependent_entity) { user }
408+
409+
it 'updates dependent entity' do
410+
expect { entity.reload.update_attribute(:updated_at, Time.now) }.to change { dependent_entity.reload.updated_at }
411+
end
412+
end
413+
414+
context 'when relation is has_many with inverse_of' do
415+
let(:entity) { user_role }
416+
417+
it_behaves_like 'dependent entity updating'
418+
end
419+
420+
context 'when relation is has_one with inverse_of' do
421+
let(:entity) { user_profile }
422+
423+
it_behaves_like 'dependent entity updating'
424+
end
425+
426+
context 'when relation is belongs_to with inverse_of' do
427+
let(:entity) { company }
428+
429+
it_behaves_like 'dependent entity updating'
430+
end
431+
432+
context 'when relation is has_one through another association with inverse_of' do
433+
let(:entity) { company_address }
434+
435+
it_behaves_like 'dependent entity updating'
436+
end
437+
end
369438
end

spec/support/database_schema.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,28 @@
3737
create_table(:payers) do |t|
3838
t.timestamps null: false
3939
end
40+
41+
create_table(:companies) do |t|
42+
t.timestamps null: false
43+
end
44+
45+
create_table(:company_addresses) do |t|
46+
t.belongs_to :company
47+
t.timestamps null: false
48+
end
49+
50+
create_table(:users) do |t|
51+
t.belongs_to :company
52+
t.timestamps null: false
53+
end
54+
55+
create_table(:user_profiles) do |t|
56+
t.belongs_to :user
57+
t.timestamps null: false
58+
end
59+
60+
create_table(:user_roles) do |t|
61+
t.belongs_to :user
62+
t.timestamps null: false
63+
end
4064
end

0 commit comments

Comments
 (0)