metabolical 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.8.7
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in metabolical.gemspec
4
+ gemspec
5
+ group :test do
6
+ gem 'activerecord'
7
+ gem 'sqlite3'
8
+ gem 'shoulda'
9
+ end
data/README.rdoc ADDED
@@ -0,0 +1,30 @@
1
+ = Metabolical
2
+
3
+ Metabolical is an ActiveRecord Model & mixin that adds metadata to your AR classes.
4
+ Whenever you feel like adding a column to a table ask yourself if what you really want is just some metadata.
5
+
6
+ == Install
7
+
8
+ gem install metabolical
9
+
10
+ == Usage
11
+
12
+ class User < ActiveRecord::Base
13
+ metabolize!
14
+ end
15
+
16
+ user = User.new
17
+ user.metas['active'] = true
18
+ user.metas['active'].data #=> true
19
+
20
+ == Notes
21
+
22
+ Metabolical will need you to run the following migration
23
+
24
+ create_table :meta_data, :force => true do |t|
25
+ t.integer :metabolized_id
26
+ t.string :metabolized_type
27
+ t.string :key
28
+ t.text :data
29
+ t.timestamps
30
+ end
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rubygems/package_task'
7
+
8
+
9
+ task :default => :test
10
+ Rake::TestTask.new(:test) do |test|
11
+ test.libs << 'lib' << 'test'
12
+ test.pattern = 'test/*_test.rb'
13
+ test.verbose = true
14
+ end
15
+
16
+ # ROOT = File.expand_path(File.dirname(__FILE__))
17
+ # TEST_ROOT = ROOT + "/test"
18
+ # MODELS_ROOT = TEST_ROOT + "/models"
19
+ # FIXTURES_ROOT = TEST_ROOT + "/fixtures"
20
+ # MIGRATIONS_ROOT = TEST_ROOT + "/migrations"
21
+ # SCHEMA_ROOT = TEST_ROOT + "/schema"
22
+ #
23
+ # ActiveRecord::Base.establish_connection(
24
+ # :adapter => "sqlite3",
25
+ # :database => "db/test.sqlite3"
26
+ # )
27
+ # load SCHEMA_ROOT + "/schema.rb"
@@ -0,0 +1,29 @@
1
+ require 'metabolical/meta_datum'
2
+ require 'metabolical/scopes'
3
+
4
+ module Metabolical
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def metabolize!
11
+ include Metabolical::Scopes
12
+
13
+ class_eval do
14
+ has_many :metas, :as => :metabolized, :class_name => 'Metabolical::MetaDatum' do
15
+ def [](key)
16
+ find_by_key(key) || self.proxy_owner.metas.detect{|m| m.key == key}
17
+ end
18
+
19
+ def []=(key, data)
20
+ meta = self[key] || self.proxy_owner.metas.build(:key => key)
21
+ meta.data = data
22
+ meta
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,6 @@
1
+ module Metabolical
2
+ class MetaDatum < ActiveRecord::Base
3
+ belongs_to :metabolized, :polymorphic => true
4
+ serialize :data
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ module Metabolical
2
+ module Scopes
3
+ def self.included(klass)
4
+ method = klass.respond_to?(:named_scope) ? :named_scope : :scope
5
+ klass.send method, :with_meta, lambda{|k| {:joins => [:metas], :conditions => {"meta_data.key" => k}}}
6
+ klass.send method, :with_metas, :includes => [:metas]
7
+ klass.send method, :with_meta_data, lambda{|k, v| {:joins => [:metas], :conditions => {"meta_data.key" => k, "meta_data.data" => v.to_yaml}}}
8
+ klass.send method, :without_meta, lambda{|k|
9
+ {:joins => [:metas],
10
+ :conditions => ["meta_data.metabolized_id not in (?)",
11
+ klass.send(:with_meta, k).all(:select => 'distinct(metabolized_id)').map(&:metabolized_id)]}
12
+ }
13
+ end
14
+
15
+ module AR3Scopes
16
+ def self.included(klass)
17
+ class_eval do
18
+ scope :with_meta, lambda{|k| joins([:meta]).where({"meta_data.key" => k}) }
19
+ scope :with_metas, includes(:meta)
20
+ scope :with_meta_data, lambda{|k, v| joins(:meta).where("meta_data.key" => k, "meta_data.data" => v.to_yaml)}
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Metabolical
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "metabolical/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "metabolical"
7
+ s.version = Metabolical::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Diego Scataglini"]
10
+ s.email = ["diego@junivi.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{This is an ActiveRecord Model & mixin to add meta data to any AR object}
13
+ s.description = %q{This is an ActiveRecord Model & mixin to add meta data to any AR object}
14
+
15
+ s.required_ruby_version = '>= 1.8.7'
16
+
17
+ s.rubyforge_project = "metabolical"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency('activerecord', '>= 2.1.2')
25
+ s.add_dependency('activesupport', '>= 2.1.2')
26
+ s.add_dependency('activemodel', '>= 2.1.2')
27
+ s.add_dependency('arel', '~> 2.0.10')
28
+ s.add_dependency('tzinfo', '~> 0.3.23')
29
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'sqlite3'
3
+ require 'active_record'
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+
7
+ TEST_ROOT = File.expand_path(File.dirname(__FILE__))
8
+ MODELS_ROOT = TEST_ROOT + "/models"
9
+ FIXTURES_ROOT = TEST_ROOT + "/fixtures"
10
+ MIGRATIONS_ROOT = TEST_ROOT + "/migrations"
11
+ SCHEMA_ROOT = TEST_ROOT + "/schema"
12
+
13
+ ActiveRecord::Base.establish_connection(
14
+ :adapter => "sqlite3",
15
+ :database => "db/test.sqlite3"
16
+ )
17
+
18
+ load SCHEMA_ROOT + "/schema.rb"
@@ -0,0 +1,96 @@
1
+ require 'helper'
2
+ require 'models/user'
3
+
4
+ class MetabolicalTest < Test::Unit::TestCase
5
+ context "an ActiveRecord Object" do
6
+
7
+ context "new record" do
8
+ setup do
9
+ @user = User.new
10
+ end
11
+
12
+ teardown do
13
+ @user.destroy
14
+ end
15
+
16
+ should "be able to assign a single meta before saving and retrieving it after save" do
17
+ @user.metas['foo'] = 'bar'
18
+ @user.save
19
+ assert_equal 'bar', @user.metas['foo'].data
20
+ end
21
+
22
+ should "be able to assign a single meta before saving and retrieving it before save" do
23
+ @user.metas['foo'] = 'bar'
24
+ assert_equal 'bar', @user.metas['foo'].data
25
+ end
26
+ end
27
+
28
+ context "saved record" do
29
+ setup do
30
+ @user = User.new
31
+ @user.save
32
+ end
33
+
34
+ teardown do
35
+ @user.destroy
36
+ end
37
+
38
+ should "be able to assign a single meta before re saving and retrieving it after save" do
39
+ @user.metas['foo'] = 'bar'
40
+ @user.save
41
+ assert_equal 'bar', @user.metas['foo'].data
42
+ end
43
+
44
+ should "be able to assign a single meta before re saving and retrieving it before save" do
45
+ @user.metas['foo'] = 'baz'
46
+ assert_equal 'baz', @user.metas['foo'].data
47
+ end
48
+
49
+ should "be able to retrieve after saving" do
50
+ @user.metas['foo'] = 'faz'
51
+ @user.save
52
+ user = User.find @user.id
53
+ assert_equal 'faz', user.metas['foo'].data
54
+ end
55
+
56
+ end
57
+
58
+ context "named scopes" do
59
+ setup do
60
+ @foo_user = User.create(:name => 'foo_user', :metas => [Metabolical::MetaDatum.new(:key => "foo", :data => "bar")])
61
+ @bar_user = User.create(:name => 'bar_user', :metas => [Metabolical::MetaDatum.new(:key => "bar", :data => "baz"),
62
+ Metabolical::MetaDatum.new(:key => "fuu", :data => "bar")])
63
+ @true_user = User.create(:name => 'true_user', :metas => [Metabolical::MetaDatum.new(:key => "bar", :data => true)])
64
+ end
65
+
66
+ teardown do
67
+ User.delete_all
68
+ end
69
+
70
+ should "have with_meta scopes" do
71
+ assert_equal [@foo_user], User.with_meta("foo")
72
+ assert_equal [@bar_user, @true_user], User.with_meta("bar")
73
+ end
74
+
75
+ should "have with_meta scopes that check for data" do
76
+ assert_equal [], User.with_meta_data("foo", "foo")
77
+ assert_equal [@foo_user], User.with_meta_data("foo", "bar"), "Should have brought back foo user"
78
+ assert_equal [@true_user], User.with_meta_data("bar", true), "Should have brought back true user"
79
+ end
80
+
81
+ should "have with_metas scope that includes all metas" do
82
+ assert User.respond_to?(:with_metas)
83
+ end
84
+
85
+ should "bring back objects without a certain meta" do
86
+ assert_equal [@foo_user], User.without_meta("bar")
87
+ end
88
+
89
+
90
+
91
+ end
92
+
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,5 @@
1
+ require 'metabolical'
2
+ class User < ActiveRecord::Base
3
+ include Metabolical
4
+ metabolize!
5
+ end
@@ -0,0 +1,18 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table :users, :force => true do |t|
4
+ t.string :name
5
+ t.timestamps
6
+ end
7
+
8
+ create_table :meta_data, :force => true do |t|
9
+ t.integer :metabolized_id
10
+ t.string :metabolized_type
11
+ t.string :key
12
+ t.text :data
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :meta_data, [:metabolized_id, :metabolized_type, :key]
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metabolical
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Diego Scataglini
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-03 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 2
32
+ - 1
33
+ - 2
34
+ version: 2.1.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: activesupport
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 2
48
+ - 1
49
+ - 2
50
+ version: 2.1.2
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: activemodel
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 2
64
+ - 1
65
+ - 2
66
+ version: 2.1.2
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: arel
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 27
78
+ segments:
79
+ - 2
80
+ - 0
81
+ - 10
82
+ version: 2.0.10
83
+ type: :runtime
84
+ version_requirements: *id004
85
+ - !ruby/object:Gem::Dependency
86
+ name: tzinfo
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ hash: 61
94
+ segments:
95
+ - 0
96
+ - 3
97
+ - 23
98
+ version: 0.3.23
99
+ type: :runtime
100
+ version_requirements: *id005
101
+ description: This is an ActiveRecord Model & mixin to add meta data to any AR object
102
+ email:
103
+ - diego@junivi.com
104
+ executables: []
105
+
106
+ extensions: []
107
+
108
+ extra_rdoc_files: []
109
+
110
+ files:
111
+ - .gitignore
112
+ - .rvmrc
113
+ - Gemfile
114
+ - README.rdoc
115
+ - Rakefile
116
+ - lib/metabolical.rb
117
+ - lib/metabolical/meta_datum.rb
118
+ - lib/metabolical/scopes.rb
119
+ - lib/metabolical/version.rb
120
+ - metabolical.gemspec
121
+ - test/helper.rb
122
+ - test/metabolical_test.rb
123
+ - test/models/user.rb
124
+ - test/schema/schema.rb
125
+ has_rdoc: true
126
+ homepage: ""
127
+ licenses: []
128
+
129
+ post_install_message:
130
+ rdoc_options: []
131
+
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ hash: 57
140
+ segments:
141
+ - 1
142
+ - 8
143
+ - 7
144
+ version: 1.8.7
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 3
151
+ segments:
152
+ - 0
153
+ version: "0"
154
+ requirements: []
155
+
156
+ rubyforge_project: metabolical
157
+ rubygems_version: 1.3.7
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: This is an ActiveRecord Model & mixin to add meta data to any AR object
161
+ test_files:
162
+ - test/helper.rb
163
+ - test/metabolical_test.rb
164
+ - test/models/user.rb
165
+ - test/schema/schema.rb