Skip to content

Instantly share code, notes, and snippets.

@tomdalling
Created May 22, 2020 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomdalling/bc585d824466d102e635d5d03502e095 to your computer and use it in GitHub Desktop.
Save tomdalling/bc585d824466d102e635d5d03502e095 to your computer and use it in GitHub Desktop.
Alternative naming for `DelegatedTypes`
# Schema: entries[ id, account_id, creator_id, created_at, updated_at, specialization_type, specialization_id ]
class Entry < ApplicationRecord
has_specialization types: %w[ Message Comment ]
belongs_to :account
belongs_to :creator
end
# Schema: messages[ id, subject ]
class Message < ApplicationRecord
is_specialization_of 'Entry'
end
# Schema: comments[ id, content ]
class Comment < ApplicationRecord
is_specialization_of 'Entry'
end
# Entry#specialization_class => +Message+ or +Comment+
# Entry#specialization_name => "message" or "comment"
# Entry.specialization => message record, or comment record
# Entry.messages => Entry.where(specialization_type: "Message")
# Entry#message? => true when specialization_type == "Message"
# Entry#message => returns the message record, when specialization_type == "Message", otherwise nil
# Entry#message_id => returns specialization_id, when entryable_type == "Message", otherwise nil
# Entry.comments => Entry.where(specialization_type: "Comment")
# Entry#comment? => true when specialization_type == "Comment"
# Entry#comment => returns the comment record, when specialization_type == "Comment", otherwise nil
# Entry#comment_id => returns entryable_id, when specialization_type == "Comment", otherwise nil
################################################################################
# Association is named "specialization" by default, because 99% of the time you
# only ever want one, but can be named manually to avoid conflicts if needed
class Entry < ApplicationRecord
has_specialization :entryable, types: %w[ Message Comment ]
has_specialization :variant, types: %w[ Mobile Desktop ]
end
# Entry#entryable_class => +Message+ or +Comment+
# Entry#entryable_name => "message" or "comment"
# Entry#entryable => message record, or comment record
#
# Entry#variant_class => +Mobile+ or +Desktop+
# Entry#variant_name => "mobile" or "desktop"
# Entry#variant => mobile record, or desktop record
@katakeynii
Copy link

Hi Tom, What you think about using instead of has_specialization use can_be and is_a in specialization classes

class Entry < ApplicationRecord
  can_be types: %w[ Message Comment ]
end

class Message < ApplicationRecord
  is_a 'Entry'
end

class Comment < ApplicationRecord
  is_a 'Entry'
end

@tomdalling
Copy link
Author

@katakeynii I like it! The only thing to look out for is that is_a sounds a lot like inheritance, so it's probably more ambiguous to some readers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment