Skip to content

Instantly share code, notes, and snippets.

@masone
Created June 27, 2014 14:30
Show Gist options
  • Save masone/20695e18343bba67c9fd to your computer and use it in GitHub Desktop.
Save masone/20695e18343bba67c9fd to your computer and use it in GitHub Desktop.
[101] pry(main)> ParanoidAttributes.only(Person.all, :id, :first_name).first.first_name
=> "Harry"
[102] pry(main)> ParanoidAttributes.only(Person.all, :id, :first_name).first.last_name
ArgumentError: Accessing excluded field last_name
[103] pry(main)> ParanoidAttributes.only(Person.all, :id, :first_name).first.bla
NoMethodError: undefined method `bla' for #<Person:0x007fe9ebbb2768>
class ParanoidAttributes
include Enumerable
attr_accessor :criteria
attr_accessor :klass
attr_accessor :blacklisted_attributes
attr_accessor :records
def self.only(criteria, *attrs)
self.new(criteria, :whitelist, attrs)
end
def self.without(criteria, *attrs)
self.new(criteria, :blacklist, attrs)
end
def initialize(criteria, action, attrs)
self.criteria = criteria
self.klass = criteria.klass
if action == :whitelist
whitelist(attrs)
elsif action == :blacklist
blacklist(attrs)
end
self.protect_attributes
end
def whitelist(attrs)
self.records = criteria.only(*attrs)
self.blacklisted_attributes = klass.fields.keys - attrs.map(&:to_s)
end
def blacklist(attrs)
self.records = criteria.without(*attrs)
self.blacklisted_attributes = attrs.map(&:to_s)
end
def protect_attributes
blacklisted_attributes = self.blacklisted_attributes
klass.class_eval do
blacklisted_attributes.each do |attr|
define_method attr do
raise ArgumentError, "Accessing excluded field #{attr}"
end
end
end
end
def each &block
records.each do |record|
if block_given?
block.call record
else
yield record
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment