Skip to content

Instantly share code, notes, and snippets.

@kaspth
Created June 10, 2023 14:42
Show Gist options
  • Save kaspth/614930361b3d2dba6361a6be198ab560 to your computer and use it in GitHub Desktop.
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.
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