Created
June 10, 2023 14:42
-
-
Save kaspth/614930361b3d2dba6361a6be198ab560 to your computer and use it in GitHub Desktop.
Making Ruby better at object proxying, so we don't need to add `user_name` etc. for Law of Demeter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Object::Proxy < SimpleDelegator | |
def initialize(object, **values) | |
super(object) | |
@values = values | |
end | |
def method_missing(name, ...) | |
@values.fetch(name) { super } | |
end | |
end | |
module Object::Proxied | |
def self.included(klass) | |
klass.define_singleton_method(:proxied) { |object = new, **values| Object::Proxy.new(object, **values) } | |
end | |
def proxied(**values) | |
self.class.proxied(self, **values) | |
end | |
end | |
class User < Data.define(:name, :email_address) | |
include Object::Proxied | |
end | |
class Post | |
# belongs_to :user | |
def user = super || build_user.proxied(name: "Unknown") | |
end | |
Post.new.user.name # => "Unknown" | |
Post.new.user.save! # => true # The User model doesn't have to know about and then guard against "Unknown" being saved to the database. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment