has_extra_data 0.1 → 0.2
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/.rspec +2 -0
- data/README +66 -35
- data/has_extra_data.gemspec +1 -1
- data/lib/has_extra_data/hook.rb +39 -4
- data/lib/has_extra_data/version.rb +1 -1
- data/spec/has_extra_data.rb +35 -18
- data/spec/spec_helper.rb +25 -5
- data/spec/test_classes.rb +27 -0
- metadata +6 -3
data/.rspec
ADDED
data/README
CHANGED
@@ -1,48 +1,79 @@
|
|
1
|
-
Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table. Use with STI to keep your database clean.
|
1
|
+
Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table. Use with STI to keep your database clean. It removes the need to have lots of nullable columns.
|
2
2
|
|
3
|
-
|
3
|
+
Usage
|
4
|
+
---------
|
5
|
+
Use in Rails 3 app. Add to bundler:
|
6
|
+
gem "has_extra_data"
|
4
7
|
|
5
|
-
|
8
|
+
Tests
|
9
|
+
---------
|
10
|
+
Uses rspec for testing.
|
11
|
+
Run tests with rspec spec/*
|
6
12
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
Todo
|
14
|
+
---------
|
15
|
+
* Automatically load extra data class with main class.
|
16
|
+
* Automatically load associations in main class.
|
17
|
+
* Automatically pass attributes through to main class.
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
Coke.first.is_diet?
|
19
|
+
Example
|
20
|
+
---------
|
15
21
|
|
16
|
-
|
17
|
-
--------
|
22
|
+
Usage:
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
24
|
+
Account.each do |account|
|
25
|
+
puts account.balance
|
26
|
+
end
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
BankAccount.each do |bank_account|
|
29
|
+
puts bank_account.balance
|
30
|
+
puts bank_account.bank_account.name
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
33
|
+
Classes:
|
34
|
+
class Account < ActiveRecord::Base
|
35
|
+
before_create :set_initial_balance
|
36
|
+
|
37
|
+
private
|
38
|
+
def set_initial_balance
|
39
|
+
self.balance = 0
|
40
|
+
true
|
41
|
+
end
|
42
|
+
end
|
28
43
|
|
29
|
-
class
|
30
|
-
|
31
|
-
|
32
|
-
end
|
44
|
+
class BankAccount < Account
|
45
|
+
has_extra_data do
|
46
|
+
belongs_to :bank
|
47
|
+
end
|
48
|
+
end
|
33
49
|
|
34
|
-
|
50
|
+
class CreditCard < Account
|
51
|
+
has_extra_data
|
52
|
+
end
|
35
53
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
54
|
+
class Bank < ActiveRecord::Base
|
55
|
+
has_one :bank_account
|
56
|
+
end
|
40
57
|
|
41
|
-
|
42
|
-
t.integer :coke_id, :null => false # Foreign key here...
|
43
|
-
t.boolean :is_diet, :null => false
|
44
|
-
end
|
58
|
+
Database Schema:
|
45
59
|
|
46
|
-
|
47
|
-
|
48
|
-
|
60
|
+
create_table :accounts do |t|
|
61
|
+
t.float :balance
|
62
|
+
end
|
63
|
+
|
64
|
+
create_table :bank_account_data do |t|
|
65
|
+
t.integer :bank_account_id, :null => false
|
66
|
+
t.integer :bank_id, :null => false
|
67
|
+
t.string :account_number, :null => false
|
68
|
+
t.string :sort_code, :null => false
|
69
|
+
end
|
70
|
+
|
71
|
+
create_table :credit_card_data do |t|
|
72
|
+
t.integer :credit_card_id, :null => false
|
73
|
+
t.string :credit_card_number, :null => false
|
74
|
+
t.date :expiry_date, :null => false
|
75
|
+
end
|
76
|
+
|
77
|
+
create_table :banks do |t|
|
78
|
+
t.string :name, :null => false
|
79
|
+
end
|
data/has_extra_data.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.email = ["jez.walker@gmail.com"]
|
11
11
|
s.homepage = ""
|
12
12
|
s.summary = %q{Ruby Rails - Add extra data to SDI models with clean database tables.}
|
13
|
-
s.description = %q{Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table.
|
13
|
+
s.description = %q{Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table. Means you can use STI but keep your database clean.}
|
14
14
|
|
15
15
|
s.add_dependency "rails"
|
16
16
|
s.add_development_dependency "rspec-rails"
|
data/lib/has_extra_data/hook.rb
CHANGED
@@ -1,16 +1,51 @@
|
|
1
1
|
module HasExtraData
|
2
2
|
module Hook
|
3
|
-
|
3
|
+
|
4
|
+
######
|
5
|
+
# has_extra_data(options = {})
|
6
|
+
#
|
7
|
+
# In it's most raw form, this method creates an associated Data class,
|
8
|
+
# which seamlessly adds attributes and methods to the main class
|
9
|
+
#
|
10
|
+
# If passed a block, extra attributes can be set on the data table,
|
11
|
+
# methods (e.g. has_many) can be called, and other methods can be defined.
|
12
|
+
#
|
13
|
+
# Options:
|
14
|
+
# table_name: The table name of the class
|
15
|
+
#####
|
16
|
+
def has_extra_data(options = {}, &block)
|
4
17
|
|
5
|
-
table_name = "#{self.name.underscore.gsub("/", "_")}_data"
|
18
|
+
table_name = options[:table_name] || "#{self.name.underscore.gsub("/", "_")}_data"
|
6
19
|
klass = Class.new(ActiveRecord::Base) do
|
7
20
|
set_table_name(table_name)
|
8
21
|
end
|
9
22
|
klass.class_eval &block if block_given?
|
10
23
|
self.const_set "Data", klass
|
11
|
-
|
24
|
+
|
25
|
+
# Add a reference to a data object that gets created when this is created
|
12
26
|
has_one :data, :class_name => "#{self.name}::Data"
|
13
|
-
before_create :
|
27
|
+
before_create :get_data
|
28
|
+
|
29
|
+
# A helper method which gets the existing data or builds a new object
|
30
|
+
define_method :get_data do
|
31
|
+
data || build_data
|
32
|
+
end
|
33
|
+
|
34
|
+
# Override respond_to? to check both this object and its data object.
|
35
|
+
define_method "respond_to?" do |sym, include_private = false|
|
36
|
+
super(sym, include_private) || get_data.respond_to?(sym, include_private)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Override method_missing to check both this object and it's data object for any methods or magic functionality.
|
40
|
+
# Firstly, try the original method_missing because there may well be
|
41
|
+
# some magic piping that will return a result and then try the data object.
|
42
|
+
define_method :method_missing do |sym, *args|
|
43
|
+
begin
|
44
|
+
super(sym, args)
|
45
|
+
rescue
|
46
|
+
get_data.send(sym, *args)
|
47
|
+
end
|
48
|
+
end
|
14
49
|
end
|
15
50
|
end
|
16
51
|
end
|
data/spec/has_extra_data.rb
CHANGED
@@ -1,30 +1,47 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "
|
3
|
+
describe "Extra data models" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@bank = Bank.create!(:name => "My Bank")
|
7
|
+
@bank_account = BankAccount.new
|
8
|
+
@valid_bank_account_attributes = {:account_number => "12345678", :sort_code => "12 34 56", :bank => @bank}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "have the data method" do
|
12
|
+
@bank_account.should respond_to(:data)
|
13
|
+
end
|
4
14
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@
|
10
|
-
|
15
|
+
it "can have variables set" do
|
16
|
+
@bank_account.account_number = "12345678"
|
17
|
+
@bank_account.sort_code = "12 34 56"
|
18
|
+
@bank_account.bank = @bank
|
19
|
+
@bank_account.save!
|
20
|
+
@bank_account.data.id.should_not == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
it "creates data with the test class" do
|
24
|
+
@bank_account.attributes = @valid_bank_account_attributes
|
25
|
+
@bank_account.save!
|
26
|
+
@bank_account.data.id.should_not == 0
|
11
27
|
end
|
12
28
|
|
13
|
-
it "
|
14
|
-
|
15
|
-
|
16
|
-
|
29
|
+
it "can read attributes" do
|
30
|
+
@bank_account.attributes = @valid_bank_account_attributes
|
31
|
+
@bank_account.save!
|
32
|
+
@bank_account = BankAccount.find(@bank_account.id)
|
33
|
+
@bank_account.account_number.should == "12345678"
|
17
34
|
end
|
18
35
|
|
19
|
-
it "
|
20
|
-
@
|
21
|
-
@
|
36
|
+
it "can read associations" do
|
37
|
+
@bank_account.attributes = @valid_bank_account_attributes
|
38
|
+
@bank_account.save!
|
39
|
+
@bank_account = BankAccount.find(@bank_account.id)
|
40
|
+
@bank_account.bank.should == @bank
|
22
41
|
end
|
23
42
|
|
24
|
-
it "
|
25
|
-
|
26
|
-
obj = @klass.create!
|
27
|
-
obj.data.id.should_not == 0
|
43
|
+
it "can have any table name" do
|
44
|
+
SillyAccount.create!
|
28
45
|
end
|
29
46
|
|
30
47
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,7 @@ require 'active_record'
|
|
6
6
|
|
7
7
|
$:.unshift File.dirname(__FILE__) + '/../lib'
|
8
8
|
|
9
|
-
#
|
9
|
+
# Thie first line isn't working so I have added the second...
|
10
10
|
require File.dirname(__FILE__) + '/../lib/has_extra_data'
|
11
11
|
ActiveRecord::Base.send(:extend, HasExtraData::Hook)
|
12
12
|
|
@@ -17,10 +17,30 @@ $stdout = StringIO.new
|
|
17
17
|
|
18
18
|
ActiveRecord::Base.logger
|
19
19
|
ActiveRecord::Schema.define(:version => 1) do
|
20
|
-
create_table :
|
20
|
+
create_table :accounts do |t|
|
21
|
+
t.float :balance
|
21
22
|
end
|
22
23
|
|
23
|
-
create_table :
|
24
|
-
t.integer :
|
24
|
+
create_table :bank_account_data do |t|
|
25
|
+
t.integer :bank_account_id, :null => false
|
26
|
+
t.integer :bank_id, :null => false
|
27
|
+
t.string :account_number, :null => false
|
28
|
+
t.string :sort_code, :null => false
|
25
29
|
end
|
26
|
-
|
30
|
+
|
31
|
+
create_table :credit_card_data do |t|
|
32
|
+
t.integer :credit_card_id, :null => false
|
33
|
+
t.string :credit_card_number, :null => false
|
34
|
+
t.date :expiry_date, :null => false
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :banks do |t|
|
38
|
+
t.string :name, :null => false
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :silly_table_name do |t|
|
42
|
+
t.integer :silly_account_id, :null => false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
require 'test_classes'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Account < ActiveRecord::Base
|
2
|
+
before_create :set_initial_balance
|
3
|
+
|
4
|
+
private
|
5
|
+
def set_initial_balance
|
6
|
+
self.balance = 0
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class BankAccount < Account
|
12
|
+
has_extra_data do
|
13
|
+
belongs_to :bank
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class CreditCard < Account
|
18
|
+
has_extra_data
|
19
|
+
end
|
20
|
+
|
21
|
+
class SillyAccount < Account
|
22
|
+
has_extra_data :table_name => "silly_table_name"
|
23
|
+
end
|
24
|
+
|
25
|
+
class Bank < ActiveRecord::Base
|
26
|
+
has_one :bank_account
|
27
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: has_extra_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: "0.
|
5
|
+
version: "0.2"
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jeremy Walker
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-17 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
version: "0"
|
36
36
|
type: :development
|
37
37
|
version_requirements: *id002
|
38
|
-
description: Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table.
|
38
|
+
description: Adds an add_extra_data method to ActiveRecord that invisibly includes an extra data table. Means you can use STI but keep your database clean.
|
39
39
|
email:
|
40
40
|
- jez.walker@gmail.com
|
41
41
|
executables: []
|
@@ -46,6 +46,7 @@ extra_rdoc_files: []
|
|
46
46
|
|
47
47
|
files:
|
48
48
|
- .gitignore
|
49
|
+
- .rspec
|
49
50
|
- Gemfile
|
50
51
|
- README
|
51
52
|
- Rakefile
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- lib/has_extra_data/version.rb
|
57
58
|
- spec/has_extra_data.rb
|
58
59
|
- spec/spec_helper.rb
|
60
|
+
- spec/test_classes.rb
|
59
61
|
has_rdoc: true
|
60
62
|
homepage: ""
|
61
63
|
licenses: []
|
@@ -87,3 +89,4 @@ summary: Ruby Rails - Add extra data to SDI models with clean database tables.
|
|
87
89
|
test_files:
|
88
90
|
- spec/has_extra_data.rb
|
89
91
|
- spec/spec_helper.rb
|
92
|
+
- spec/test_classes.rb
|