mini_record 0.2.0 → 0.2.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/README.md +23 -41
- data/lib/mini_record/auto_schema.rb +43 -12
- data/lib/mini_record/version.rb +1 -1
- data/spec/mini_record_spec.rb +74 -4
- data/spec/models.rb +6 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -31,32 +31,21 @@ Remember that inside properties you can use all migrations methods,
|
|
31
31
|
see [documentation](http://api.rubyonrails.org/classes/ActiveRecord/Migration.html)
|
32
32
|
|
33
33
|
``` rb
|
34
|
-
class Person < ActiveRecord::Base
|
35
|
-
schema do |s|
|
36
|
-
s.string :name
|
37
|
-
s.integer :address_id
|
38
|
-
end
|
39
|
-
add_index :address_id
|
40
|
-
|
41
|
-
belongs_to :address
|
42
|
-
end
|
43
|
-
Person.auto_upgrade!
|
44
|
-
|
45
|
-
# you can use also this SEXY way
|
46
34
|
class Post < ActiveRecord::Base
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
35
|
+
col :title_en, :title_jp
|
36
|
+
col :description_en, :description_jp, :as => :text
|
37
|
+
col :permalink, :index => true, :limit => 50
|
38
|
+
col :comments_count, :as => :integer
|
39
|
+
col :category, :as => :references, :index => true
|
51
40
|
end
|
52
41
|
Post.auto_upgrade!
|
53
42
|
```
|
54
43
|
|
55
|
-
If you don't like `
|
44
|
+
If you don't like `col` there are also few aliases: `key, field, property, attribute`
|
56
45
|
|
57
46
|
Instead of `:as => :my_type` you can use `:type => :my_type`
|
58
47
|
|
59
|
-
Option `:as` or `:type` if not provided
|
48
|
+
Option `:as` or `:type` if not provided is `:string` by default, you can use all ActiveRecord types:
|
60
49
|
|
61
50
|
``` rb
|
62
51
|
:primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean
|
@@ -70,8 +59,8 @@ You can provide others ActiveRecord options like:
|
|
70
59
|
|
71
60
|
# example
|
72
61
|
class Foo < ActiveRecord::Base
|
73
|
-
|
74
|
-
|
62
|
+
col :title, :default => "MyTitle" # :as => :string is by default
|
63
|
+
col :price, :as => :decimal, :scale => 8, :precision => 2
|
75
64
|
end
|
76
65
|
```
|
77
66
|
|
@@ -81,28 +70,21 @@ for more details.
|
|
81
70
|
Finally, when you execute `MyModel.auto_upgrade!`, missing columns, indexes and tables will be created on the fly.
|
82
71
|
Indexes and columns present in the db but **not** in your model schema will be **deleted*** also in your db.
|
83
72
|
|
73
|
+
### Single Table Inheritance
|
74
|
+
|
75
|
+
MiniRecord as ActiveRecord support STI plus some goodness, see our specs for more details.
|
76
|
+
|
84
77
|
### Adding a new column
|
85
78
|
|
86
79
|
Super easy, open your model and just add it:
|
87
80
|
|
88
81
|
``` rb
|
89
|
-
class Person < ActiveRecord::Base
|
90
|
-
schema do |s|
|
91
|
-
s.string :name
|
92
|
-
s.string :surname # <<- this
|
93
|
-
s.integer :address_id
|
94
|
-
end
|
95
|
-
belongs_to :address
|
96
|
-
end
|
97
|
-
Person.auto_upgrade!
|
98
|
-
|
99
|
-
# or you can use a more interesting way
|
100
82
|
class Post < ActiveRecord::Base
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
83
|
+
col :title
|
84
|
+
col :body, :as => :text # <<- this
|
85
|
+
col :permalink, :index => true
|
86
|
+
col :comments_count, :as => :integer
|
87
|
+
col :category, :as => :references, :index => true
|
106
88
|
end
|
107
89
|
Post.auto_upgrade!
|
108
90
|
```
|
@@ -133,10 +115,10 @@ Note that writing it in DSL way you have same options as `add_index` so you are
|
|
133
115
|
|
134
116
|
``` rb
|
135
117
|
class Fox < ActiveRecord::Base
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
118
|
+
col :foo, :index => true
|
119
|
+
col :foo, :index => :custom_name
|
120
|
+
col :foo, :index => [:foo, :bar]
|
121
|
+
col :foo, :index => { :column => [:branch_id, :party_id], :unique => true, :name => 'by_branch_party' }
|
140
122
|
end
|
141
123
|
```
|
142
124
|
|
@@ -144,7 +126,7 @@ That is the same of:
|
|
144
126
|
|
145
127
|
``` rb
|
146
128
|
class Fox < ActiveRecord::Base
|
147
|
-
|
129
|
+
col :foo
|
148
130
|
add_index :foo
|
149
131
|
add_index :custom_name
|
150
132
|
add_index [:foo, :bar]
|
@@ -5,40 +5,60 @@ module MiniRecord
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
+
|
8
9
|
def table_definition
|
10
|
+
return superclass.table_definition unless superclass == ActiveRecord::Base
|
11
|
+
|
9
12
|
@_table_definition ||= begin
|
10
13
|
tb = ActiveRecord::ConnectionAdapters::TableDefinition.new(connection)
|
11
14
|
tb.primary_key(primary_key)
|
15
|
+
tb
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
19
|
+
def indexes
|
20
|
+
return superclass.indexes unless superclass == ActiveRecord::Base
|
21
|
+
|
22
|
+
@_indexes ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def col(*args)
|
26
|
+
return unless connection?
|
27
|
+
|
28
|
+
options = args.extract_options!
|
16
29
|
type = options.delete(:as) || options.delete(:type) || :string
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
args.each do |column_name|
|
31
|
+
table_definition.send(type, column_name, options)
|
32
|
+
column_name = table_definition.columns[-1].name
|
33
|
+
case index_name = options.delete(:index)
|
34
|
+
when Hash
|
35
|
+
add_index(options.delete(:column) || column_name, index_name)
|
36
|
+
when TrueClass
|
37
|
+
add_index(column_name)
|
38
|
+
when String, Symbol, Array
|
39
|
+
add_index(index_name)
|
40
|
+
end
|
26
41
|
end
|
27
42
|
end
|
28
43
|
alias :key :col
|
29
44
|
alias :property :col
|
30
45
|
alias :field :col
|
46
|
+
alias :attribute :col
|
31
47
|
|
32
48
|
def reset_table_definition!
|
33
49
|
@_table_definition = nil
|
34
50
|
end
|
51
|
+
alias :reset_schema! :reset_table_definition!
|
35
52
|
|
36
53
|
def schema
|
37
54
|
reset_table_definition!
|
38
55
|
yield table_definition
|
56
|
+
table_definition
|
39
57
|
end
|
40
58
|
alias :keys :schema
|
41
59
|
alias :properties :schema
|
60
|
+
alias :fields :schema
|
61
|
+
alias :attributes :schema
|
42
62
|
|
43
63
|
def add_index(column_name, options={})
|
44
64
|
index_name = connection.index_name(table_name, :column => column_name)
|
@@ -47,11 +67,16 @@ module MiniRecord
|
|
47
67
|
end
|
48
68
|
alias :index :add_index
|
49
69
|
|
50
|
-
def
|
51
|
-
|
70
|
+
def connection?
|
71
|
+
!!connection
|
72
|
+
rescue Exception => e
|
73
|
+
puts "\e[31m%s\e[0m" % e.message.strip
|
74
|
+
false
|
52
75
|
end
|
53
76
|
|
54
77
|
def auto_upgrade!
|
78
|
+
return unless connection?
|
79
|
+
|
55
80
|
# Table doesn't exist, create it
|
56
81
|
unless connection.tables.include?(table_name)
|
57
82
|
# TODO: Add to create_table options
|
@@ -73,6 +98,12 @@ module MiniRecord
|
|
73
98
|
hash
|
74
99
|
end
|
75
100
|
|
101
|
+
# Add to schema inheritance column if necessary
|
102
|
+
if descendants.present? && !fields_in_schema.include?(inheritance_column.to_s)
|
103
|
+
table_definition.column inheritance_column, :string
|
104
|
+
end
|
105
|
+
|
106
|
+
|
76
107
|
# Remove fields from db no longer in schema
|
77
108
|
(fields_in_db.keys - fields_in_schema.keys & fields_in_db.keys).each do |field|
|
78
109
|
column = fields_in_db[field]
|
data/lib/mini_record/version.rb
CHANGED
data/spec/mini_record_spec.rb
CHANGED
@@ -55,7 +55,7 @@ describe MiniRecord do
|
|
55
55
|
person.name.must_equal 'foo'
|
56
56
|
end
|
57
57
|
|
58
|
-
it 'has #key,col,property inside model' do
|
58
|
+
it 'has #key,col,property,attribute inside model' do
|
59
59
|
ActiveRecord::Base.connection.table_exists?(Post.table_name).must_equal false
|
60
60
|
ActiveRecord::Base.connection.table_exists?(Category.table_name).must_equal false
|
61
61
|
Post.auto_upgrade!; Category.auto_upgrade!
|
@@ -74,8 +74,8 @@ describe MiniRecord do
|
|
74
74
|
# Remove a column
|
75
75
|
Post.reset_table_definition!
|
76
76
|
Post.class_eval do
|
77
|
-
|
78
|
-
|
77
|
+
col :name
|
78
|
+
col :category, :as => :references
|
79
79
|
end
|
80
80
|
Post.auto_upgrade!
|
81
81
|
post = Post.first
|
@@ -100,10 +100,80 @@ describe MiniRecord do
|
|
100
100
|
|
101
101
|
# Add a new index
|
102
102
|
Animal.class_eval do
|
103
|
-
|
103
|
+
col :category, :as => :references, :index => true
|
104
104
|
end
|
105
105
|
Animal.auto_upgrade!
|
106
106
|
Animal.db_columns.must_include "category_id"
|
107
107
|
Animal.db_indexes.must_equal((indexes_was << "index_animals_on_category_id").sort)
|
108
108
|
end
|
109
|
+
|
110
|
+
it 'works with STI' do
|
111
|
+
class Dog < Pet; end
|
112
|
+
class Cat < Pet; end
|
113
|
+
Pet.auto_upgrade!
|
114
|
+
|
115
|
+
# Check inheritance column
|
116
|
+
Pet.db_columns.wont_include "type"
|
117
|
+
Dog.auto_upgrade!
|
118
|
+
Pet.db_columns.must_include "type"
|
119
|
+
|
120
|
+
# Now, let's we know if STI is working
|
121
|
+
Pet.create(:name => "foo")
|
122
|
+
Dog.create(:name => "bar")
|
123
|
+
Dog.count.must_equal 1
|
124
|
+
Dog.first.name.must_equal "bar"
|
125
|
+
Pet.count.must_equal 2
|
126
|
+
Pet.all.map(&:name).must_equal ["foo", "bar"]
|
127
|
+
|
128
|
+
# Check that this doesn't break things
|
129
|
+
Cat.auto_upgrade!
|
130
|
+
Dog.first.name.must_equal "bar"
|
131
|
+
|
132
|
+
# What's happen if we change schema?
|
133
|
+
Dog.table_definition.must_equal Pet.table_definition
|
134
|
+
Dog.indexes.must_equal Pet.indexes
|
135
|
+
Dog.class_eval do
|
136
|
+
col :bau
|
137
|
+
end
|
138
|
+
Dog.auto_upgrade!
|
139
|
+
Pet.db_columns.must_include "bau"
|
140
|
+
Dog.new.must_respond_to :bau
|
141
|
+
Cat.new.must_respond_to :bau
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'works with custom inheritance column' do
|
145
|
+
class User < ActiveRecord::Base
|
146
|
+
col :name
|
147
|
+
col :surname
|
148
|
+
col :role
|
149
|
+
set_inheritance_column :role
|
150
|
+
end
|
151
|
+
class Administrator < User; end
|
152
|
+
class Customer < User; end
|
153
|
+
|
154
|
+
User.auto_upgrade!
|
155
|
+
Administrator.create(:name => "Davide", :surname => "D'Agostino")
|
156
|
+
Customer.create(:name => "Foo", :surname => "Bar")
|
157
|
+
Administrator.count.must_equal 1
|
158
|
+
Administrator.first.name.must_equal "Davide"
|
159
|
+
Customer.count.must_equal 1
|
160
|
+
Customer.first.name.must_equal "Foo"
|
161
|
+
User.count.must_equal 2
|
162
|
+
User.first.role.must_equal "Administrator"
|
163
|
+
User.last.role.must_equal "Customer"
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'allow multiple columns definitions' do
|
167
|
+
class Fake < ActiveRecord::Base
|
168
|
+
col :name, :surname
|
169
|
+
col :category, :group, :as => :references
|
170
|
+
end
|
171
|
+
Fake.auto_upgrade!
|
172
|
+
Fake.create(:name => 'foo', :surname => 'bar', :category_id => 1, :group_id => 2)
|
173
|
+
fake = Fake.first
|
174
|
+
fake.name.must_equal 'foo'
|
175
|
+
fake.surname.must_equal 'bar'
|
176
|
+
fake.category_id.must_equal 1
|
177
|
+
fake.group_id.must_equal 2
|
178
|
+
end
|
109
179
|
end
|
data/spec/models.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Davide D'Agostino
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-11 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|