Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facilitate an ApplicationRecord::AssociatedObject #28

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
26 changes: 13 additions & 13 deletions lib/active_record/associated_object.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
3 changes: 3 additions & 0 deletions test/boot/associated_object.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
Loading