metabolical 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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