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 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