DelegateClass
will help you in this.Person
. Users in the system can sell something and / or publish articles. Subclasses here will not work, because the user can be both an author and a seller at the same time. We'll refactor. class Person < ActiveRecord::Base has_many :articles # has_many :comments, :through => :articles # has_many :items # has_many :transactions # # ? def is_seller? items.present? end # def amount_owed # => end # ? def is_author? articles.present? end # ? def can_post_article_to_homepage? # => end end
class Person < ActiveRecord::Base # ... has_many :purchased_items # has_many :purchased_transactions # # ? def is_buyer? purchased_items.present? end # ... end
ActiveRecord
, all these has_many
no longer work. In fact, you need to rewrite the class from scratch, the development of a new functionality is postponed.Person
class, its functionality can be extended with delegate classes: # class Person < ActiveRecord::Base end # class Seller < DelegateClass(Person) delegate :id, :to => :__getobj__ # def items Item.for_seller_id(id) end # def transactions Transaction.for_seller_id(id) end # ? def is_seller? items.present? end # def amount_owed # => end end # class Author < DelegateClass(Person) delegate :id, :to => :__getobj__ # def articles Article.for_author_id(id) end # def comments Comment.for_author_id(id) end # def is_author? articles.present? end # ? def can_post_article_to_homepage? # => end end
person = Person.find(1) person.items
person = Person.find(1) seller = Seller.new(person) seller.items seller.first_name # => person.first_name
# class Buyer < DelegateClass(Person) delegate :id, :to => :__getobj__ # def purchased_items Item.for_buyer_id(id) end # ? def is_buyer? purchased_items.present? end end
#reload
: person = Person.find(1) seller = Seller.new(person) seller.class # => Seller seller.reload.class # => Person
#id
method is not delegated. To get AcitveRecord#id
, add this line to the delegate class: delegate :id, :to => :__getobj__
DelegateClass
: require 'delegate' class Animal end class Dog < DelegateClass(Animal) end animal = Animal.new dog = Dog.new(animal) dog.eql?(dog) # => false, WTF? O_o
#eql?
called for the base object (in this case, animal
): dog.eql?(animal) # => true
#equal?
not delegated by default: dog.equal?(dog) # => true dog.equal?(animal) # => false
Source: https://habr.com/ru/post/149454/
All Articles