Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernie Miller committed Jan 27, 2011
0 parents commit 2593027
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
pkg/*
*.gem
.bundle
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in attr_bucket.gemspec
gemspec
20 changes: 20 additions & 0 deletions LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2011 Ernie Miller

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7 changes: 7 additions & 0 deletions README.rdoc
@@ -0,0 +1,7 @@
= attr_bucket

This is probably a horrible idea.

== Copyright

Copyright (c) 2011 {Ernie Miller}[http://metautonomo.us]. See LICENSE for details.
2 changes: 2 additions & 0 deletions Rakefile
@@ -0,0 +1,2 @@
require 'bundler'
Bundler::GemHelper.install_tasks
23 changes: 23 additions & 0 deletions attr_bucket.gemspec
@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "attr_bucket/version"

Gem::Specification.new do |s|
s.name = "attr_bucket"
s.version = AttrBucket::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Ernie Miller"]
s.email = ["ernie@metautonomo.us"]
s.homepage = "http://metautonomo.us"
s.summary = %q{This is probably a horrible idea.}
s.description = %q{A really, really, horrible idea.}

s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])

s.rubyforge_project = "attr_bucket"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
end
72 changes: 72 additions & 0 deletions lib/attr_bucket.rb
@@ -0,0 +1,72 @@
module AttrBucket
def self.included(base)
base.extend ClassMethods
end

private

def get_attr_bucket(name)
unless read_attribute(name).is_a?(Hash)
write_attribute(name, {})
end
read_attribute(name)
end

def explicitly_type_cast(value, type)
return nil if value.nil?
case type
when :string then value.to_s
when :text then value.to_s
when :integer then value.to_i rescue value ? 1 : 0
when :float then value.to_f
when :decimal then self.class.value_to_decimal(value)
when :datetime then self.class.string_to_time(value)
when :timestamp then self.class.string_to_time(value)
when :time then self.class.string_to_dummy_time(value)
when :date then self.class.string_to_date(value)
when :binary then self.class.binary_to_string(value)
when :boolean then self.class.value_to_boolean(value)
else value
end
end

module ClassMethods
private

def attr_bucket(opts = {})
opts.map do |bucket_name, attrs|
serialize bucket_name, Hash

if attrs.is_a?(Hash)
attrs.map do|attr_name, attr_type|
define_bucket_reader bucket_name, attr_name
define_bucket_writer bucket_name, attr_name, attr_type
end
else
Array.wrap(attrs).each do |attr_name|
define_bucket_reader bucket_name, attr_name
define_bucket_writer bucket_name, attr_name, :string
end
end
end
end

def define_bucket_reader(bucket_name, attr_name)
define_method attr_name do
get_attr_bucket(bucket_name)[attr_name]
end unless method_defined? attr_name
end

def define_bucket_writer(bucket_name, attr_name, attr_type)
define_method "#{attr_name}=" do |val|
# TODO: Make this more resilient/granular for multiple bucketed changes
send("#{bucket_name}_will_change!")
get_attr_bucket(bucket_name)[attr_name] = explicitly_type_cast(val, attr_type)
end unless method_defined? "#{attr_name}="
end
end
end

require 'active_record'

ActiveRecord::Base.send(:include, AttrBucket)
3 changes: 3 additions & 0 deletions lib/attr_bucket/version.rb
@@ -0,0 +1,3 @@
module AttrBucket
VERSION = "0.1.0"
end

0 comments on commit 2593027

Please sign in to comment.