mini_record 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
- key :title
48
- key :permalink, :index => true, :limit => 50
49
- key :comments_count, :as => :integer
50
- key :category, :as => :references, :index => true
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 `key` there are also few aliases: `col, field, property`
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 are `:string`, you can use all ActiveRecord types:
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
- key :title, :default => "MyTitle" # :as => :string is by default
74
- key :price, :as => :decimal, :scale => 8, :precision => 2
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
- key :title
102
- key :body, :as => :text # <<- this
103
- key :permalink, :index => true
104
- key :comments_count, :as => :integer
105
- key :category, :as => :references, :index => true
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
- key :foo, :index => true
137
- key :foo, :index => :custom_name
138
- key :foo, :index => [:foo, :bar]
139
- key :foo, :index => { :column => [:branch_id, :party_id], :unique => true, :name => 'by_branch_party' }
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
- key :foo
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 col(column_name, options={})
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
- table_definition.send(type, column_name, options)
18
- column_name = table_definition.columns[-1].name
19
- case index_name = options.delete(:index)
20
- when Hash
21
- add_index(options.delete(:column) || column_name, index_name)
22
- when TrueClass
23
- add_index(column_name)
24
- when String, Symbol, Array
25
- add_index(index_name)
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 indexes
51
- @_indexes ||= {}
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]
@@ -1,3 +1,3 @@
1
1
  module MiniRecord
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -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
- key :name
78
- key :category, :as => :references
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
- key :category, :as => :references, :index => true
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
@@ -52,3 +52,9 @@ class Animal < ActiveRecord::Base
52
52
  key :name, :index => true
53
53
  index :id
54
54
  end
55
+
56
+ class Pet < ActiveRecord::Base
57
+ include SpecHelper
58
+
59
+ key :name, :index => true
60
+ end
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: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
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-10 00:00:00 +02:00
18
+ date: 2011-09-11 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency