diff --git a/README.md b/README.md index 816bf7c..4725731 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,17 @@ You can see real life examples in these blog posts: If your team is using Associated Objects, we're more than happy to feature any write ups here. +### Setting up an `ApplicationRecord::AssociatedObject` + +In case you need to define default logic exclusive to your Associated Objects you can set up a common base class in `app/models/application_record/associated_object.rb`. + +```ruby +class ApplicationRecord::AssociatedObject < ActiveRecord::AssociatedObject +end +``` + +We'll set this up when you run the generator below too. + ### Use the generator to help write Associated Objects To set up the `Post::Publisher` from above, you can call `bin/rails generate associated Post::Publisher`. diff --git a/lib/active_record/associated_object.rb b/lib/active_record/associated_object.rb index 9747090..4008622 100644 --- a/lib/active_record/associated_object.rb +++ b/lib/active_record/associated_object.rb @@ -1,19 +1,19 @@ class ActiveRecord::AssociatedObject class << self - def inherited(klass) - record_klass = klass.module_parent - record_name = klass.module_parent_name.demodulize.underscore - attribute_name = klass.to_s.demodulize.underscore.to_sym - - unless record_klass.respond_to?(:descends_from_active_record?) && record_klass.descends_from_active_record? - raise ArgumentError, "#{record_klass} isn't valid; can only associate with ActiveRecord::Base subclasses" - end - - klass.alias_method record_name, :record - klass.define_singleton_method(:record_klass) { record_klass } - klass.define_singleton_method(:attribute_name) { attribute_name } - klass.delegate :record_klass, :attribute_name, to: :class + def associate_with_record + record_klass = module_parent + record_name = module_parent_name.demodulize.underscore + attribute_name = to_s.demodulize.underscore.to_sym + + raise ArgumentError, "#{record_klass} isn't valid; can only associate with ActiveRecord::Base subclasses" \ + unless record_klass.respond_to?(:descends_from_active_record?) && record_klass.descends_from_active_record? + + alias_method record_name, :record + define_singleton_method(:record_klass) { record_klass } + define_singleton_method(:attribute_name) { attribute_name } + delegate :record_klass, :attribute_name, to: :class end + def inherited(klass) = klass.associate_with_record def extension(&block) record_klass.class_eval(&block) diff --git a/test/boot/associated_object.rb b/test/boot/associated_object.rb index d723278..4d8cd43 100644 --- a/test/boot/associated_object.rb +++ b/test/boot/associated_object.rb @@ -1,5 +1,8 @@ class ApplicationRecord::AssociatedObject < ActiveRecord::AssociatedObject; end +p ApplicationRecord::AssociatedObject.record_klass +p ApplicationRecord::AssociatedObject.attribute_name + class Author::Archiver < ApplicationRecord::AssociatedObject; end # TODO: Replace with Data.define once on Ruby 3.2. Author::Classified = Struct.new(:author)