Skip to content

Instantly share code, notes, and snippets.

@tooky
Created August 8, 2012 10:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tooky/3294185 to your computer and use it in GitHub Desktop.
Save tooky/3294185 to your computer and use it in GitHub Desktop.
require 'delegate'
class ProtectionProxy < SimpleDelegator
def initialize(object, *writable_fields)
super(object)
@writable_fields = writable_fields
end
def method_missing(method, *args, &block)
method_name = method.to_s
if !method_name.end_with?('=')
super
elsif @writable_fields.include?(method_name[0...-1].to_sym)
super
end
end
end
require 'rspec-given'
require 'delegate'
class ProtectionProxy < SimpleDelegator
def initialize(object, *writable_fields)
super(object)
@object = object
@writable_fields = writable_fields
end
def update_attributes(attributes={})
attrs = attributes.select { |field_name|
@writable_fields.include?(field_name)
}
@object.update_attributes attrs
end
def method_missing(method, *args, &block)
method_name = method.to_s
if !method_name.end_with?('=')
super
elsif @writable_fields.include?(method_name[0...-1].to_sym)
super
end
end
end
class User < Struct.new(:name, :email, :membership_level)
def update_attributes(attributes={})
attributes.each do |key, value|
send(:"#{key}=", value)
end
end
end
describe User do
Given(:user) { User.new("Jim", "jim@somewhere", "Beginner") }
When {
user.update_attributes(:name => "Joe",
:membership_level => 'Advanced')
}
Then { user.name.should == "Joe" }
Then { user.membership_level.should == "Advanced" }
end
describe ProtectionProxy do
Given(:user) { User.new("Jim", "jim@somewhere", "Beginner") }
Given(:proxy) { ProtectionProxy.new(user, :membership_level) }
Then { proxy.name.should == "Jim" }
context "when modifiying a writable field" do
When { proxy.membership_level = "Advanced" }
Then { proxy.membership_level.should == "Advanced" }
end
context "when modifiying a non-writable field" do
When { proxy.name = "Joe" }
Then { proxy.name.should == "Jim" }
end
context 'when update attributes is called' do
When {
proxy.update_attributes(:name => "Joe",
:membership_level => 'Advanced')
}
Then { proxy.membership_level.should == "Advanced" }
Then { proxy.name.should == "Jim" }
end
end
require 'rspec-given'
require 'protection_proxy'
class User < Struct.new(:name, :email, :membership_level)
end
describe ProtectionProxy do
Given(:user) { User.new("Jim", "jim@somewhere", "Beginner") }
Given(:proxy) { ProtectionProxy.new(user, :membership_level) }
Then { proxy.name.should == "Jim" }
context "when modifiying a writable field" do
When { proxy.membership_level = "Advanced" }
Then { proxy.membership_level.should == "Advanced" }
end
context "when modifiying a non-writable field" do
When { proxy.name = "Joe" }
Then { proxy.name.should == "Jim" }
end
end
class ProtectionProxy < SimpleDelegator
def initialize(object, *writable_fields)
super(object)
@object = object
@writable_fields = writable_fields
end
def update_attributes(attributes={})
attrs = attributes.select { |field_name|
@writable_fields.include?(field_name)
}
@object.update_attributes attrs
end
end
class UserController < ActionController::Base
def update
user = User.find(params[:id])
proxy = ProtectionProxy.new(user, :name, :email)
if proxy.update_attributes(params[:user])
# happy path
else
# error
end
end
end
require 'delegate'
class Capitalise < SimpleDelegator
def initialize(source)
@source = source
super(source)
end
def name
@source.name.upcase
end
end
class Person < Struct.new(:name)
def greet
"Hello, #{name}"
end
end
john = Person.new('john')
capital_john = Capitalise.new(john)
john.greet #=> "Hello, john"
capital_john.greet #=> "Hello, john"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment