Skip to content

Commit 1890eca

Browse files
authored
BREAKING: Replace record_klass with record & remove record_klass/attribute_name instance methods. (#35)
We're removing `record_klass` at both the instance and class level. We're also removing `attribute_name` at the instance level. In hindsight I don't think either of the instance level methods are that helpful. Add this for full backwards compatibility though: ```ruby ActiveRecord::AssociatedObject.alias_method :record_klass, :record ActiveRecord::AssociatedObject.delegate :record_klass, :attribute_name, to: :class ``` Feel free to open an issue and explain how you're using these too! ---- We're also refactoring the internals here: - We're extending ActiveModel::Naming to get `model_name` which is also useful for later features. - We're eagerly defining the `record` and `attribute_name` methods, so people don't get `NoMethodError`'s. - ^ but we'll still eagerly check the namespace is an `ActiveRecord::Base`` and verify it. - We're using a double-dispatch refactoring in `associated_via` to slim `inherited` and make accessing the new object class's internals easier. This is some of the oldest code in here, so I'm almost a little moody touching it. 😢
1 parent 31f5a36 commit 1890eca

File tree

2 files changed

+20
-29
lines changed

2 files changed

+20
-29
lines changed

lib/active_record/associated_object.rb

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
class ActiveRecord::AssociatedObject
2+
extend ActiveModel::Naming
3+
24
class << self
3-
def inherited(klass)
4-
record_klass = klass.module_parent
5-
record_name = klass.module_parent_name.demodulize.underscore
6-
attribute_name = klass.to_s.demodulize.underscore.to_sym
5+
def inherited(new_object)
6+
new_object.associated_via(new_object.module_parent)
7+
end
78

8-
unless record_klass.respond_to?(:descends_from_active_record?) && record_klass.descends_from_active_record?
9-
raise ArgumentError, "#{record_klass} isn't valid; can only associate with ActiveRecord::Base subclasses"
9+
def associated_via(record)
10+
unless record.respond_to?(:descends_from_active_record?) && record.descends_from_active_record?
11+
raise ArgumentError, "#{record} isn't a valid namespace; can only associate with ActiveRecord::Base subclasses"
1012
end
1113

12-
klass.alias_method record_name, :record
13-
klass.define_singleton_method(:record) { record_klass }
14-
klass.define_singleton_method(:record_klass) { record_klass }
15-
klass.define_singleton_method(:attribute_name) { attribute_name }
16-
klass.delegate :record_klass, :attribute_name, to: :class
14+
@record, @attribute_name = record, model_name.element.to_sym
15+
alias_method record.model_name.element, :record
1716
end
1817

18+
attr_reader :record, :attribute_name
19+
delegate :primary_key, :unscoped, :transaction, to: :record
20+
1921
def extension(&block)
20-
record_klass.class_eval(&block)
22+
record.class_eval(&block)
2123
end
2224

23-
def respond_to_missing?(...) = record_klass.respond_to?(...) || super
24-
delegate :unscoped, :transaction, :primary_key, to: :record_klass
25-
2625
def method_missing(method, ...)
27-
if !record_klass.respond_to?(method) then super else
28-
record_klass.public_send(method, ...).then do |value|
26+
if !record.respond_to?(method) then super else
27+
record.public_send(method, ...).then do |value|
2928
value.respond_to?(:each) ? value.map(&attribute_name) : value&.public_send(attribute_name)
3029
end
3130
end
3231
end
32+
def respond_to_missing?(...) = record.respond_to?(...) || super
3333
end
3434

3535
attr_reader :record

test/active_record/associated_object_test.rb

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,13 @@ class ActiveRecord::AssociatedObjectTest < ActiveSupport::TestCase
4343
end
4444

4545
test "introspection" do
46-
assert_equal Post, @publisher.record_klass
47-
assert_equal Post, Post::Publisher.record_klass
48-
49-
assert_equal :publisher, @publisher.attribute_name
46+
assert_equal Post, Post::Publisher.record
5047
assert_equal :publisher, Post::Publisher.attribute_name
5148

52-
assert_equal Author, @archiver.record_klass
53-
assert_equal Author, Author::Archiver.record_klass
54-
55-
assert_equal :archiver, @archiver.attribute_name
49+
assert_equal Author, Author::Archiver.record
5650
assert_equal :archiver, Author::Archiver.attribute_name
5751

58-
assert_equal Post::Comment, @rating.record_klass
59-
assert_equal Post::Comment, Post::Comment::Rating.record_klass
60-
61-
assert_equal :rating, @rating.attribute_name
52+
assert_equal Post::Comment, Post::Comment::Rating.record
6253
assert_equal :rating, Post::Comment::Rating.attribute_name
6354
end
6455

0 commit comments

Comments
 (0)