diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1996f..a09cc3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## [Unreleased] +- Fix compatibility with Rails `delegated_type` by accepting optional `scope` parameter in `safe_polymorphic` method signature + ## [0.1.0] - 2022-12-28 - Initial release @@ -11,4 +13,4 @@ ## [0.1.2] - 2022-12-28 -- Fix issue that forced to declare the I18n locale (`class_not_allowed`) in each project using this gem instead of using the default locale included in the gem \ No newline at end of file +- Fix issue that forced to declare the I18n locale (`class_not_allowed`) in each project using this gem instead of using the default locale included in the gem diff --git a/Gemfile.lock b/Gemfile.lock index d78c5dd..00b675e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -114,6 +114,7 @@ GEM PLATFORMS arm64-darwin-21 arm64-darwin-23 + arm64-darwin-24 x86_64-linux DEPENDENCIES diff --git a/lib/safe_polymorphic/associations.rb b/lib/safe_polymorphic/associations.rb index 322efab..a02c830 100644 --- a/lib/safe_polymorphic/associations.rb +++ b/lib/safe_polymorphic/associations.rb @@ -11,8 +11,8 @@ class << base end module ClassMethods - def safe_polymorphic(name, **options) - unsafe_polymorphic name, **options + def safe_polymorphic(name, scope = nil, **options) + unsafe_polymorphic name, scope, **options polymorphic = options[:polymorphic] return unless polymorphic.present? && polymorphic.class != TrueClass diff --git a/spec/safe_polymorphic/associations_spec.rb b/spec/safe_polymorphic/associations_spec.rb index 5560821..216a866 100644 --- a/spec/safe_polymorphic/associations_spec.rb +++ b/spec/safe_polymorphic/associations_spec.rb @@ -205,4 +205,65 @@ end end end + + describe 'with delegated_type' do + before do + Book.create(title: 'Book', owner: User.first) + end + it 'should work alongside delegated_type without errors' do + expect(Address).to respond_to(:addressable_types) + expect(Address.respond_to?(:with_addressable_user)).to be true + expect(Address.respond_to?(:with_addressable_publisher)).to be true + end + + it 'should create an Address with a User addressable' do + user = User.first + address = Address.new(addressable: user, delegated: Book.first) + + expect(address.addressable_type).to eq('User') + expect(address.addressable).to eq(user) + end + + it 'should create an Address with a Publisher addressable' do + publisher = Publisher.first + address = Address.new(addressable: publisher, delegated: Book.first) + + expect(address.addressable_type).to eq('Publisher') + expect(address.addressable).to eq(publisher) + end + + it 'should have safe_polymorphic helper methods working' do + expect(Address.addressable_types).to match_array([User, Publisher]) + end + + it 'should reject invalid addressable types' do + other = OtherThing.create + address = Address.new(addressable: other, delegated: Book.first) + + expect(address).to_not be_valid + expect(address.errors[:addressable_type]).to include('OtherThing is not an allowed class') + end + + it 'should provide scopes for safe_polymorphic' do + user = User.first + publisher = Publisher.first + + Address.create(addressable: user, delegated: Book.first) + Address.create(addressable: publisher, delegated: Book.first) + + expect(Address.with_addressable_user.count).to eq(1) + expect(Address.with_addressable_publisher.count).to eq(1) + end + + it 'should provide class methods of delegated_type ' do + user = User.first + book = Book.first + + address = Address.create(addressable: user, delegated: book) + + expect(Address.with_addressable_user.first).to eq(address) + expect(address.addressable).to eq(user) + expect(address.delegated).to eq(book) + end + end end diff --git a/spec/support/models.rb b/spec/support/models.rb index 1b45c65..f62170b 100644 --- a/spec/support/models.rb +++ b/spec/support/models.rb @@ -4,3 +4,4 @@ require_relative 'models/publisher' require_relative 'models/book' require_relative 'models/other_thing' +require_relative 'models/address' diff --git a/spec/support/models/address.rb b/spec/support/models/address.rb new file mode 100644 index 0000000..4e7cc0b --- /dev/null +++ b/spec/support/models/address.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class Address < ActiveRecord::Base + belongs_to :addressable, polymorphic: [Publisher, User] + delegated_type :delegated, types: %w[Book], dependent: :destroy +end diff --git a/spec/support/schema.rb b/spec/support/schema.rb index d531fa1..13d3064 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -29,4 +29,13 @@ t.timestamps end + + create_table :addresses, force: true do |t| + t.integer :addressable_id + t.string :addressable_type + t.bigint :delegated_id, null: false + t.string :delegated_type, null: false + + t.timestamps + end end