Delegated Type supports customizeable foreign_type column
This commit is contained in:
parent
2e81ed6d10
commit
1f61fd65ae
@ -1,3 +1,10 @@
|
||||
* Respect `foreign_type` option to `delegated_type` for `{role}_class` method.
|
||||
|
||||
Usage of `delegated_type` with non-conventional `{role}_type` column names can now be specified with `foreign_type` option.
|
||||
This option is the same as `foreign_type` as forwarded to the underlying `belongs_to` association that `delegated_type` wraps.
|
||||
|
||||
*Jason Karns*
|
||||
|
||||
* Add support for unique constraints (PostgreSQL-only).
|
||||
|
||||
```ruby
|
||||
|
@ -192,6 +192,11 @@ module DelegatedType
|
||||
# +role+ with an "_id" suffix. So a class that defines a
|
||||
# <tt>delegated_type :entryable, types: %w[ Message Comment ]</tt> association will use "entryable_id" as
|
||||
# the default <tt>:foreign_key</tt>.
|
||||
# [:foreign_type]
|
||||
# Specify the column used to store the associated object's type. By default this is inferred to be the passed
|
||||
# +role+ with a "_type" suffix. A class that defines a
|
||||
# <tt>delegated_type :entryable, types: %w[ Message Comment ]</tt> association will use "entryable_type" as
|
||||
# the default <tt>:foreign_type</tt>.
|
||||
# [:primary_key]
|
||||
# Specify the method that returns the primary key of associated object used for the convenience methods.
|
||||
# By default this is +id+.
|
||||
@ -211,11 +216,11 @@ def delegated_type(role, types:, **options)
|
||||
private
|
||||
def define_delegated_type_methods(role, types:, options:)
|
||||
primary_key = options[:primary_key] || "id"
|
||||
role_type = "#{role}_type"
|
||||
role_type = options[:foreign_type] || "#{role}_type"
|
||||
role_id = options[:foreign_key] || "#{role}_id"
|
||||
|
||||
define_method "#{role}_class" do
|
||||
public_send("#{role}_type").constantize
|
||||
public_send(role_type).constantize
|
||||
end
|
||||
|
||||
define_method "#{role}_name" do
|
||||
|
@ -11,11 +11,12 @@
|
||||
require "models/uuid_comment"
|
||||
|
||||
class DelegatedTypeTest < ActiveRecord::TestCase
|
||||
fixtures :comments, :accounts
|
||||
fixtures :comments, :accounts, :posts
|
||||
|
||||
setup do
|
||||
@entry_with_message = Entry.create! entryable: Message.new(subject: "Hello world!"), account: accounts(:signals37)
|
||||
@entry_with_comment = Entry.create! entryable: comments(:greetings), account: accounts(:signals37)
|
||||
@entry_with_post = Entry.create! thing: posts(:welcome), account: accounts(:signals37)
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
@uuid_entry_with_message = UuidEntry.create! uuid: SecureRandom.uuid, entryable: UuidMessage.new(uuid: SecureRandom.uuid, subject: "Hello world!")
|
||||
@ -28,6 +29,12 @@ class DelegatedTypeTest < ActiveRecord::TestCase
|
||||
assert_equal Comment, @entry_with_comment.entryable_class
|
||||
end
|
||||
|
||||
test "delegated class with custom foreign_type" do
|
||||
assert_equal Message, @entry_with_message.thing_class
|
||||
assert_equal Comment, @entry_with_comment.thing_class
|
||||
assert_equal Post, @entry_with_post.thing_class
|
||||
end
|
||||
|
||||
test "delegated type name" do
|
||||
assert_equal "message", @entry_with_message.entryable_name
|
||||
assert @entry_with_message.entryable_name.message?
|
||||
@ -44,11 +51,21 @@ class DelegatedTypeTest < ActiveRecord::TestCase
|
||||
assert_not @entry_with_comment.message?
|
||||
end
|
||||
|
||||
test "delegated type predicates with custom foreign_type" do
|
||||
assert @entry_with_post.post?
|
||||
assert_not @entry_with_message.post?
|
||||
assert_not @entry_with_comment.post?
|
||||
end
|
||||
|
||||
test "scope" do
|
||||
assert Entry.messages.first.message?
|
||||
assert Entry.comments.first.comment?
|
||||
end
|
||||
|
||||
test "scope with custom foreign_type" do
|
||||
assert Entry.posts.first.post?
|
||||
end
|
||||
|
||||
test "accessor" do
|
||||
assert @entry_with_message.message.is_a?(Message)
|
||||
assert_nil @entry_with_message.comment
|
||||
|
@ -3,4 +3,8 @@
|
||||
class Entry < ActiveRecord::Base
|
||||
delegated_type :entryable, types: %w[ Message Comment ]
|
||||
belongs_to :account, touch: true
|
||||
|
||||
# alternate delegation for custom foreign_key/foreign_type
|
||||
delegated_type :thing, types: %w[ Post ],
|
||||
foreign_key: :entryable_id, foreign_type: :entryable_type
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user