activerecord 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1024 -543
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -29
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +55 -44
- data/lib/active_record/aggregations.rb +40 -34
- data/lib/active_record/associations.rb +204 -276
- data/lib/active_record/associations/alias_tracker.rb +1 -1
- data/lib/active_record/associations/association.rb +30 -35
- data/lib/active_record/associations/association_scope.rb +40 -40
- data/lib/active_record/associations/belongs_to_association.rb +15 -2
- data/lib/active_record/associations/builder/association.rb +81 -28
- data/lib/active_record/associations/builder/belongs_to.rb +35 -57
- data/lib/active_record/associations/builder/collection_association.rb +54 -40
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -64
- data/lib/active_record/associations/builder/has_one.rb +13 -50
- data/lib/active_record/associations/builder/singular_association.rb +13 -13
- data/lib/active_record/associations/collection_association.rb +92 -88
- data/lib/active_record/associations/collection_proxy.rb +913 -63
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -10
- data/lib/active_record/associations/has_many_association.rb +35 -9
- data/lib/active_record/associations/has_many_through_association.rb +24 -14
- data/lib/active_record/associations/has_one_association.rb +33 -13
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -22
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_helper.rb +1 -11
- data/lib/active_record/associations/preloader.rb +14 -17
- data/lib/active_record/associations/preloader/association.rb +29 -33
- data/lib/active_record/associations/preloader/collection_association.rb +1 -1
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/has_one.rb +1 -1
- data/lib/active_record/associations/preloader/through_association.rb +13 -17
- data/lib/active_record/associations/singular_association.rb +11 -11
- data/lib/active_record/associations/through_association.rb +2 -2
- data/lib/active_record/attribute_assignment.rb +133 -153
- data/lib/active_record/attribute_methods.rb +196 -93
- data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
- data/lib/active_record/attribute_methods/dirty.rb +31 -28
- data/lib/active_record/attribute_methods/primary_key.rb +38 -30
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +62 -91
- data/lib/active_record/attribute_methods/serialization.rb +97 -66
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -45
- data/lib/active_record/attribute_methods/write.rb +32 -39
- data/lib/active_record/autosave_association.rb +56 -70
- data/lib/active_record/base.rb +53 -450
- data/lib/active_record/callbacks.rb +53 -18
- data/lib/active_record/coders/yaml_column.rb +11 -9
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +353 -197
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -131
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -19
- data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +101 -91
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +59 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +225 -96
- data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +99 -46
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +114 -36
- data/lib/active_record/connection_adapters/column.rb +46 -24
- data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -32
- data/lib/active_record/connection_adapters/mysql_adapter.rb +181 -64
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/cast.rb +132 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +347 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +158 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +448 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +454 -885
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -16
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +574 -13
- data/lib/active_record/connection_handling.rb +98 -0
- data/lib/active_record/core.rb +428 -0
- data/lib/active_record/counter_cache.rb +106 -108
- data/lib/active_record/dynamic_matchers.rb +110 -63
- data/lib/active_record/errors.rb +25 -8
- data/lib/active_record/explain.rb +8 -58
- data/lib/active_record/explain_subscriber.rb +6 -3
- data/lib/active_record/fixture_set/file.rb +56 -0
- data/lib/active_record/fixtures.rb +146 -148
- data/lib/active_record/inheritance.rb +77 -59
- data/lib/active_record/integration.rb +5 -5
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +38 -42
- data/lib/active_record/locking/pessimistic.rb +4 -4
- data/lib/active_record/log_subscriber.rb +19 -9
- data/lib/active_record/migration.rb +318 -153
- data/lib/active_record/migration/command_recorder.rb +90 -31
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/model_schema.rb +69 -92
- data/lib/active_record/nested_attributes.rb +113 -148
- data/lib/active_record/null_relation.rb +65 -0
- data/lib/active_record/persistence.rb +188 -97
- data/lib/active_record/query_cache.rb +18 -36
- data/lib/active_record/querying.rb +19 -15
- data/lib/active_record/railtie.rb +91 -36
- data/lib/active_record/railties/console_sandbox.rb +0 -2
- data/lib/active_record/railties/controller_runtime.rb +2 -2
- data/lib/active_record/railties/databases.rake +90 -309
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +7 -3
- data/lib/active_record/reflection.rb +72 -56
- data/lib/active_record/relation.rb +241 -157
- data/lib/active_record/relation/batches.rb +25 -22
- data/lib/active_record/relation/calculations.rb +143 -121
- data/lib/active_record/relation/delegation.rb +96 -18
- data/lib/active_record/relation/finder_methods.rb +117 -183
- data/lib/active_record/relation/merger.rb +133 -0
- data/lib/active_record/relation/predicate_builder.rb +90 -42
- data/lib/active_record/relation/query_methods.rb +666 -136
- data/lib/active_record/relation/spawn_methods.rb +43 -150
- data/lib/active_record/result.rb +33 -6
- data/lib/active_record/sanitization.rb +24 -50
- data/lib/active_record/schema.rb +19 -12
- data/lib/active_record/schema_dumper.rb +31 -39
- data/lib/active_record/schema_migration.rb +36 -0
- data/lib/active_record/scoping.rb +0 -124
- data/lib/active_record/scoping/default.rb +48 -45
- data/lib/active_record/scoping/named.rb +74 -103
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +9 -15
- data/lib/active_record/store.rb +119 -15
- data/lib/active_record/tasks/database_tasks.rb +158 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +138 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
- data/lib/active_record/test_case.rb +61 -38
- data/lib/active_record/timestamp.rb +8 -9
- data/lib/active_record/transactions.rb +65 -51
- data/lib/active_record/validations.rb +17 -15
- data/lib/active_record/validations/associated.rb +20 -14
- data/lib/active_record/validations/presence.rb +65 -0
- data/lib/active_record/validations/uniqueness.rb +93 -52
- data/lib/active_record/version.rb +4 -4
- data/lib/rails/generators/active_record.rb +3 -5
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -7
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -3
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- metadata +53 -46
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/session_store.rb +0 -360
- data/lib/rails/generators/active_record/migration.rb +0 -15
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
1
|
require 'date'
|
3
2
|
require 'set'
|
4
3
|
require 'bigdecimal'
|
@@ -6,7 +5,10 @@ require 'bigdecimal/util'
|
|
6
5
|
|
7
6
|
module ActiveRecord
|
8
7
|
module ConnectionAdapters #:nodoc:
|
9
|
-
|
8
|
+
# Abstract representation of an index definition on a table. Instances of
|
9
|
+
# this type are typically created and returned by methods in database
|
10
|
+
# adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
|
11
|
+
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where) #:nodoc:
|
10
12
|
end
|
11
13
|
|
12
14
|
# Abstract representation of a column definition. Instances of this type
|
@@ -20,7 +22,7 @@ module ActiveRecord
|
|
20
22
|
end
|
21
23
|
|
22
24
|
def sql_type
|
23
|
-
base.type_to_sql(type.to_sym, limit, precision, scale)
|
25
|
+
base.type_to_sql(type.to_sym, limit, precision, scale)
|
24
26
|
end
|
25
27
|
|
26
28
|
def to_sql
|
@@ -42,8 +44,8 @@ module ActiveRecord
|
|
42
44
|
# Represents the schema of an SQL table in an abstract way. This class
|
43
45
|
# provides methods for manipulating the schema representation.
|
44
46
|
#
|
45
|
-
# Inside migration files, the +t+ object in +create_table+
|
46
|
-
# is actually of this type:
|
47
|
+
# Inside migration files, the +t+ object in +create_table+ and
|
48
|
+
# +change_table+ is actually of this type:
|
47
49
|
#
|
48
50
|
# class SomeMigration < ActiveRecord::Migration
|
49
51
|
# def up
|
@@ -62,11 +64,12 @@ module ActiveRecord
|
|
62
64
|
class TableDefinition
|
63
65
|
# An array of ColumnDefinition objects, representing the column changes
|
64
66
|
# that have been defined.
|
65
|
-
attr_accessor :columns
|
67
|
+
attr_accessor :columns, :indexes
|
66
68
|
|
67
69
|
def initialize(base)
|
68
70
|
@columns = []
|
69
71
|
@columns_hash = {}
|
72
|
+
@indexes = {}
|
70
73
|
@base = base
|
71
74
|
end
|
72
75
|
|
@@ -158,21 +161,21 @@ module ActiveRecord
|
|
158
161
|
# td.column(:granted, :boolean)
|
159
162
|
# # granted BOOLEAN
|
160
163
|
#
|
161
|
-
# td.column(:picture, :binary, :
|
164
|
+
# td.column(:picture, :binary, limit: 2.megabytes)
|
162
165
|
# # => picture BLOB(2097152)
|
163
166
|
#
|
164
|
-
# td.column(:sales_stage, :string, :
|
167
|
+
# td.column(:sales_stage, :string, limit: 20, default: 'new', null: false)
|
165
168
|
# # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
|
166
169
|
#
|
167
|
-
# td.column(:bill_gates_money, :decimal, :
|
170
|
+
# td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
|
168
171
|
# # => bill_gates_money DECIMAL(15,2)
|
169
172
|
#
|
170
|
-
# td.column(:sensor_reading, :decimal, :
|
173
|
+
# td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
|
171
174
|
# # => sensor_reading DECIMAL(30,20)
|
172
175
|
#
|
173
176
|
# # While <tt>:scale</tt> defaults to zero on most databases, it
|
174
177
|
# # probably wouldn't hurt to include it.
|
175
|
-
# td.column(:huge_integer, :decimal, :
|
178
|
+
# td.column(:huge_integer, :decimal, precision: 30)
|
176
179
|
# # => huge_integer DECIMAL(30)
|
177
180
|
#
|
178
181
|
# # Defines a column with a database-specific type.
|
@@ -187,20 +190,20 @@ module ActiveRecord
|
|
187
190
|
#
|
188
191
|
# What can be written like this with the regular calls to column:
|
189
192
|
#
|
190
|
-
# create_table
|
191
|
-
# t.column
|
192
|
-
# t.column
|
193
|
-
# t.column
|
194
|
-
# t.column
|
195
|
-
# t.column
|
196
|
-
# t.column
|
193
|
+
# create_table :products do |t|
|
194
|
+
# t.column :shop_id, :integer
|
195
|
+
# t.column :creator_id, :integer
|
196
|
+
# t.column :name, :string, default: "Untitled"
|
197
|
+
# t.column :value, :string, default: "Untitled"
|
198
|
+
# t.column :created_at, :datetime
|
199
|
+
# t.column :updated_at, :datetime
|
197
200
|
# end
|
198
201
|
#
|
199
|
-
#
|
202
|
+
# can also be written as follows using the short-hand:
|
200
203
|
#
|
201
204
|
# create_table :products do |t|
|
202
205
|
# t.integer :shop_id, :creator_id
|
203
|
-
# t.string :name, :value, :
|
206
|
+
# t.string :name, :value, default: "Untitled"
|
204
207
|
# t.timestamps
|
205
208
|
# end
|
206
209
|
#
|
@@ -209,25 +212,32 @@ module ActiveRecord
|
|
209
212
|
#
|
210
213
|
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
|
211
214
|
# column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
|
212
|
-
# options, these will be used when creating the <tt>_type</tt> column.
|
215
|
+
# options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option
|
216
|
+
# will also create an index, similar to calling <tt>add_index</tt>. So what can be written like this:
|
213
217
|
#
|
214
218
|
# create_table :taggings do |t|
|
215
219
|
# t.integer :tag_id, :tagger_id, :taggable_id
|
216
220
|
# t.string :tagger_type
|
217
|
-
# t.string :taggable_type, :
|
221
|
+
# t.string :taggable_type, default: 'Photo'
|
218
222
|
# end
|
223
|
+
# add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id'
|
224
|
+
# add_index :taggings, [:tagger_id, :tagger_type]
|
219
225
|
#
|
220
226
|
# Can also be written as follows using references:
|
221
227
|
#
|
222
228
|
# create_table :taggings do |t|
|
223
|
-
# t.references :tag
|
224
|
-
# t.references :tagger, :
|
225
|
-
# t.references :taggable, :
|
229
|
+
# t.references :tag, index: { name: 'index_taggings_on_tag_id' }
|
230
|
+
# t.references :tagger, polymorphic: true, index: true
|
231
|
+
# t.references :taggable, polymorphic: { default: 'Photo' }
|
226
232
|
# end
|
227
233
|
def column(name, type, options = {})
|
228
234
|
name = name.to_s
|
229
235
|
type = type.to_sym
|
230
236
|
|
237
|
+
if primary_key_column_name == name
|
238
|
+
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
239
|
+
end
|
240
|
+
|
231
241
|
column = self[name] || new_column_definition(@base, name, type)
|
232
242
|
|
233
243
|
limit = options.fetch(:limit) do
|
@@ -242,21 +252,26 @@ module ActiveRecord
|
|
242
252
|
self
|
243
253
|
end
|
244
254
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
255
|
+
[:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
|
256
|
+
define_method column_type do |*args|
|
257
|
+
options = args.extract_options!
|
258
|
+
column_names = args
|
259
|
+
column_names.each { |name| column(name, column_type, options) }
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Adds index options to the indexes hash, keyed by column name
|
264
|
+
# This is primarily used to track indexes that need to be created after the table
|
265
|
+
#
|
266
|
+
# index(:account_id, name: 'index_projects_on_account_id')
|
267
|
+
def index(column_name, options = {})
|
268
|
+
indexes[column_name] = options
|
254
269
|
end
|
255
270
|
|
256
271
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
257
272
|
# <tt>:updated_at</tt> to the table.
|
258
273
|
def timestamps(*args)
|
259
|
-
options =
|
274
|
+
options = args.extract_options!
|
260
275
|
column(:created_at, :datetime, options)
|
261
276
|
column(:updated_at, :datetime, options)
|
262
277
|
end
|
@@ -264,9 +279,11 @@ module ActiveRecord
|
|
264
279
|
def references(*args)
|
265
280
|
options = args.extract_options!
|
266
281
|
polymorphic = options.delete(:polymorphic)
|
282
|
+
index_options = options.delete(:index)
|
267
283
|
args.each do |col|
|
268
284
|
column("#{col}_id", :integer, options)
|
269
|
-
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options)
|
285
|
+
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
286
|
+
index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options
|
270
287
|
end
|
271
288
|
end
|
272
289
|
alias :belongs_to :references
|
@@ -286,6 +303,11 @@ module ActiveRecord
|
|
286
303
|
definition
|
287
304
|
end
|
288
305
|
|
306
|
+
def primary_key_column_name
|
307
|
+
primary_key_column = columns.detect { |c| c.type == :primary_key }
|
308
|
+
primary_key_column && primary_key_column.name
|
309
|
+
end
|
310
|
+
|
289
311
|
def native
|
290
312
|
@base.native_database_types
|
291
313
|
end
|
@@ -299,6 +321,7 @@ module ActiveRecord
|
|
299
321
|
# change_table :table do |t|
|
300
322
|
# t.column
|
301
323
|
# t.index
|
324
|
+
# t.rename_index
|
302
325
|
# t.timestamps
|
303
326
|
# t.change
|
304
327
|
# t.change_default
|
@@ -331,7 +354,7 @@ module ActiveRecord
|
|
331
354
|
|
332
355
|
# Adds a new column to the named table.
|
333
356
|
# See TableDefinition#column for details of the options you can use.
|
334
|
-
#
|
357
|
+
#
|
335
358
|
# ====== Creating a simple column
|
336
359
|
# t.column(:name, :string)
|
337
360
|
def column(column_name, type, options = {})
|
@@ -346,13 +369,12 @@ module ActiveRecord
|
|
346
369
|
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
347
370
|
# an Array of Symbols. See SchemaStatements#add_index
|
348
371
|
#
|
349
|
-
# ===== Examples
|
350
372
|
# ====== Creating a simple index
|
351
373
|
# t.index(:name)
|
352
374
|
# ====== Creating a unique index
|
353
|
-
# t.index([:branch_id, :party_id], :
|
375
|
+
# t.index([:branch_id, :party_id], unique: true)
|
354
376
|
# ====== Creating a named index
|
355
|
-
# t.index([:branch_id, :party_id], :
|
377
|
+
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
356
378
|
def index(column_name, options = {})
|
357
379
|
@base.add_index(@table_name, column_name, options)
|
358
380
|
end
|
@@ -362,8 +384,15 @@ module ActiveRecord
|
|
362
384
|
@base.index_exists?(@table_name, column_name, options)
|
363
385
|
end
|
364
386
|
|
387
|
+
# Renames the given index on the table.
|
388
|
+
#
|
389
|
+
# t.rename_index(:user_id, :account_id)
|
390
|
+
def rename_index(index_name, new_index_name)
|
391
|
+
@base.rename_index(@table_name, index_name, new_index_name)
|
392
|
+
end
|
393
|
+
|
365
394
|
# Adds timestamps (+created_at+ and +updated_at+) columns to the table. See SchemaStatements#add_timestamps
|
366
|
-
#
|
395
|
+
#
|
367
396
|
# t.timestamps
|
368
397
|
def timestamps
|
369
398
|
@base.add_timestamps(@table_name)
|
@@ -371,15 +400,15 @@ module ActiveRecord
|
|
371
400
|
|
372
401
|
# Changes the column's definition according to the new options.
|
373
402
|
# See TableDefinition#column for details of the options you can use.
|
374
|
-
#
|
375
|
-
# t.change(:name, :string, :
|
403
|
+
#
|
404
|
+
# t.change(:name, :string, limit: 80)
|
376
405
|
# t.change(:description, :text)
|
377
406
|
def change(column_name, type, options = {})
|
378
407
|
@base.change_column(@table_name, column_name, type, options)
|
379
408
|
end
|
380
409
|
|
381
410
|
# Sets a new default value for a column. See SchemaStatements#change_column_default
|
382
|
-
#
|
411
|
+
#
|
383
412
|
# t.change_default(:qualification, 'new')
|
384
413
|
# t.change_default(:authorized, 1)
|
385
414
|
def change_default(column_name, default)
|
@@ -387,37 +416,36 @@ module ActiveRecord
|
|
387
416
|
end
|
388
417
|
|
389
418
|
# Removes the column(s) from the table definition.
|
390
|
-
#
|
419
|
+
#
|
391
420
|
# t.remove(:qualification)
|
392
421
|
# t.remove(:qualification, :experience)
|
393
422
|
def remove(*column_names)
|
394
|
-
@base.
|
423
|
+
@base.remove_columns(@table_name, *column_names)
|
395
424
|
end
|
396
425
|
|
397
426
|
# Removes the given index from the table.
|
398
427
|
#
|
399
|
-
# ===== Examples
|
400
428
|
# ====== Remove the index_table_name_on_column in the table_name table
|
401
429
|
# t.remove_index :column
|
402
430
|
# ====== Remove the index named index_table_name_on_branch_id in the table_name table
|
403
|
-
# t.remove_index :
|
431
|
+
# t.remove_index column: :branch_id
|
404
432
|
# ====== Remove the index named index_table_name_on_branch_id_and_party_id in the table_name table
|
405
|
-
# t.remove_index :
|
433
|
+
# t.remove_index column: [:branch_id, :party_id]
|
406
434
|
# ====== Remove the index named by_branch_party in the table_name table
|
407
|
-
# t.remove_index :
|
435
|
+
# t.remove_index name: :by_branch_party
|
408
436
|
def remove_index(options = {})
|
409
437
|
@base.remove_index(@table_name, options)
|
410
438
|
end
|
411
439
|
|
412
440
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
413
|
-
#
|
441
|
+
#
|
414
442
|
# t.remove_timestamps
|
415
443
|
def remove_timestamps
|
416
444
|
@base.remove_timestamps(@table_name)
|
417
445
|
end
|
418
446
|
|
419
447
|
# Renames a column.
|
420
|
-
#
|
448
|
+
#
|
421
449
|
# t.rename(:description, :name)
|
422
450
|
def rename(column_name, new_column_name)
|
423
451
|
@base.rename_column(@table_name, column_name, new_column_name)
|
@@ -425,61 +453,43 @@ module ActiveRecord
|
|
425
453
|
|
426
454
|
# Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
|
427
455
|
# <tt>references</tt> and <tt>belongs_to</tt> are acceptable.
|
428
|
-
#
|
429
|
-
# t.references(:
|
430
|
-
# t.
|
431
|
-
#
|
456
|
+
#
|
457
|
+
# t.references(:user)
|
458
|
+
# t.belongs_to(:supplier, polymorphic: true)
|
459
|
+
#
|
432
460
|
def references(*args)
|
433
461
|
options = args.extract_options!
|
434
|
-
|
435
|
-
|
436
|
-
@base.add_column(@table_name, "#{col}_id", :integer, options)
|
437
|
-
@base.add_column(@table_name, "#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
|
462
|
+
args.each do |ref_name|
|
463
|
+
@base.add_reference(@table_name, ref_name, options)
|
438
464
|
end
|
439
465
|
end
|
440
466
|
alias :belongs_to :references
|
441
467
|
|
442
468
|
# Removes a reference. Optionally removes a +type+ column.
|
443
469
|
# <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
|
444
|
-
#
|
445
|
-
# t.remove_references(:
|
446
|
-
# t.
|
447
|
-
#
|
470
|
+
#
|
471
|
+
# t.remove_references(:user)
|
472
|
+
# t.remove_belongs_to(:supplier, polymorphic: true)
|
473
|
+
#
|
448
474
|
def remove_references(*args)
|
449
475
|
options = args.extract_options!
|
450
|
-
|
451
|
-
|
452
|
-
@base.remove_column(@table_name, "#{col}_id")
|
453
|
-
@base.remove_column(@table_name, "#{col}_type") unless polymorphic.nil?
|
476
|
+
args.each do |ref_name|
|
477
|
+
@base.remove_reference(@table_name, ref_name, options)
|
454
478
|
end
|
455
479
|
end
|
456
|
-
alias :remove_belongs_to
|
480
|
+
alias :remove_belongs_to :remove_references
|
457
481
|
|
458
482
|
# Adds a column or columns of a specified type
|
459
|
-
#
|
483
|
+
#
|
460
484
|
# t.string(:goat)
|
461
485
|
# t.string(:goat, :sheep)
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
column = ColumnDefinition.new(@base, name.to_s, type) # column = ColumnDefinition.new(@base, name, type)
|
470
|
-
if options[:limit] # if options[:limit]
|
471
|
-
column.limit = options[:limit] # column.limit = options[:limit]
|
472
|
-
elsif native[type].is_a?(Hash) # elsif native[type].is_a?(Hash)
|
473
|
-
column.limit = native[type][:limit] # column.limit = native[type][:limit]
|
474
|
-
end # end
|
475
|
-
column.precision = options[:precision] # column.precision = options[:precision]
|
476
|
-
column.scale = options[:scale] # column.scale = options[:scale]
|
477
|
-
column.default = options[:default] # column.default = options[:default]
|
478
|
-
column.null = options[:null] # column.null = options[:null]
|
479
|
-
@base.add_column(@table_name, name, column.sql_type, options) # @base.add_column(@table_name, name, column.sql_type, options)
|
480
|
-
end # end
|
481
|
-
end # end
|
482
|
-
EOV
|
486
|
+
[:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
|
487
|
+
define_method column_type do |*args|
|
488
|
+
options = args.extract_options!
|
489
|
+
args.each do |name|
|
490
|
+
@base.add_column(@table_name, name, column_type, options)
|
491
|
+
end
|
492
|
+
end
|
483
493
|
end
|
484
494
|
|
485
495
|
private
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters # :nodoc:
|
3
|
+
# The goal of this module is to move Adapter specific column
|
4
|
+
# definitions to the Adapter instead of having it in the schema
|
5
|
+
# dumper itself. This code represents the normal case.
|
6
|
+
# We can then redefine how certain data types may be handled in the schema dumper on the
|
7
|
+
# Adapter level by over-writing this code inside the database spececific adapters
|
8
|
+
module ColumnDumper
|
9
|
+
def column_spec(column, types)
|
10
|
+
spec = prepare_column_options(column, types)
|
11
|
+
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.to_s}: ")}
|
12
|
+
spec
|
13
|
+
end
|
14
|
+
|
15
|
+
# This can be overridden on a Adapter level basis to support other
|
16
|
+
# extended datatypes (Example: Adding an array option in the
|
17
|
+
# PostgreSQLAdapter)
|
18
|
+
def prepare_column_options(column, types)
|
19
|
+
spec = {}
|
20
|
+
spec[:name] = column.name.inspect
|
21
|
+
|
22
|
+
# AR has an optimization which handles zero-scale decimals as integers. This
|
23
|
+
# code ensures that the dumper still dumps the column as a decimal.
|
24
|
+
spec[:type] = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type
|
25
|
+
'decimal'
|
26
|
+
else
|
27
|
+
column.type.to_s
|
28
|
+
end
|
29
|
+
spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit] && spec[:type] != 'decimal'
|
30
|
+
spec[:precision] = column.precision.inspect if column.precision
|
31
|
+
spec[:scale] = column.scale.inspect if column.scale
|
32
|
+
spec[:null] = 'false' unless column.null
|
33
|
+
spec[:default] = default_string(column.default) if column.has_default?
|
34
|
+
spec
|
35
|
+
end
|
36
|
+
|
37
|
+
# Lists the valid migration options
|
38
|
+
def migration_keys
|
39
|
+
[:name, :limit, :precision, :scale, :default, :null]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def default_string(value)
|
45
|
+
case value
|
46
|
+
when BigDecimal
|
47
|
+
value.to_s
|
48
|
+
when Date, DateTime, Time
|
49
|
+
"'#{value.to_s(:db)}'"
|
50
|
+
when Range
|
51
|
+
# infinity dumps as Infinity, which causes uninitialized constant error
|
52
|
+
value.inspect.gsub('Infinity', '::Float::INFINITY')
|
53
|
+
else
|
54
|
+
value.inspect
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|