activerecord 4.0.0.beta1 → 4.0.0.rc1
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 +573 -30
- data/README.rdoc +3 -3
- data/lib/active_record.rb +8 -2
- data/lib/active_record/associations.rb +16 -9
- data/lib/active_record/associations/association.rb +8 -6
- data/lib/active_record/associations/association_scope.rb +2 -1
- data/lib/active_record/associations/belongs_to_association.rb +2 -2
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/belongs_to.rb +37 -5
- data/lib/active_record/associations/collection_association.rb +38 -14
- data/lib/active_record/associations/collection_proxy.rb +18 -15
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +3 -3
- data/lib/active_record/associations/has_many_association.rb +4 -3
- data/lib/active_record/associations/has_many_through_association.rb +1 -1
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +29 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +26 -6
- data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_part.rb +6 -6
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
- data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +5 -5
- data/lib/active_record/attribute_methods.rb +20 -5
- data/lib/active_record/attribute_methods/dirty.rb +5 -1
- data/lib/active_record/attribute_methods/primary_key.rb +1 -1
- data/lib/active_record/attribute_methods/serialization.rb +9 -2
- data/lib/active_record/autosave_association.rb +19 -5
- data/lib/active_record/base.rb +3 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +8 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +3 -9
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +2 -8
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +60 -61
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +13 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +291 -153
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +92 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +55 -29
- data/lib/active_record/connection_adapters/column.rb +4 -4
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -3
- data/lib/active_record/connection_adapters/mysql_adapter.rb +5 -5
- data/lib/active_record/connection_adapters/postgresql/cast.rb +22 -2
- data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -6
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +50 -9
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +53 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +35 -7
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -5
- data/lib/active_record/connection_handling.rb +7 -7
- data/lib/active_record/core.rb +43 -8
- data/lib/active_record/counter_cache.rb +2 -1
- data/lib/active_record/errors.rb +11 -10
- data/lib/active_record/explain.rb +9 -7
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +3 -2
- data/lib/active_record/fixture_set/file.rb +1 -2
- data/lib/active_record/fixtures.rb +13 -7
- data/lib/active_record/inheritance.rb +12 -4
- data/lib/active_record/integration.rb +3 -3
- data/lib/active_record/locking/optimistic.rb +2 -2
- data/lib/active_record/log_subscriber.rb +2 -2
- data/lib/active_record/migration.rb +69 -21
- data/lib/active_record/model_schema.rb +1 -1
- data/lib/active_record/nested_attributes.rb +98 -46
- data/lib/active_record/persistence.rb +3 -3
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +18 -4
- data/lib/active_record/railties/console_sandbox.rb +3 -2
- data/lib/active_record/railties/controller_runtime.rb +2 -1
- data/lib/active_record/railties/databases.rake +38 -80
- data/lib/active_record/reflection.rb +36 -3
- data/lib/active_record/relation.rb +18 -8
- data/lib/active_record/relation/calculations.rb +10 -5
- data/lib/active_record/relation/delegation.rb +3 -5
- data/lib/active_record/relation/finder_methods.rb +27 -14
- data/lib/active_record/relation/merger.rb +30 -2
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_methods.rb +113 -16
- data/lib/active_record/runtime_registry.rb +17 -0
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/schema_migration.rb +8 -5
- data/lib/active_record/scoping.rb +56 -2
- data/lib/active_record/scoping/default.rb +12 -11
- data/lib/active_record/scoping/named.rb +7 -3
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/statement_cache.rb +26 -0
- data/lib/active_record/tasks/database_tasks.rb +55 -10
- data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +7 -2
- data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
- data/lib/active_record/timestamp.rb +6 -0
- data/lib/active_record/transactions.rb +7 -3
- data/lib/active_record/validations.rb +1 -2
- data/lib/active_record/validations/uniqueness.rb +7 -3
- data/lib/active_record/version.rb +7 -6
- data/lib/rails/generators/active_record/migration/migration_generator.rb +9 -2
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -1
- metadata +17 -12
- data/examples/associations.png +0 -0
@@ -107,7 +107,11 @@ module ActiveRecord
|
|
107
107
|
|
108
108
|
def changes_from_zero_to_string?(old, value)
|
109
109
|
# For columns with old 0 and value non-empty string
|
110
|
-
old == 0 && value.is_a?(String) && value.present? && value
|
110
|
+
old == 0 && value.is_a?(String) && value.present? && non_zero?(value)
|
111
|
+
end
|
112
|
+
|
113
|
+
def non_zero?(value)
|
114
|
+
value !~ /\A0+(\.0+)?\z/
|
111
115
|
end
|
112
116
|
end
|
113
117
|
end
|
@@ -11,6 +11,12 @@ module ActiveRecord
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module ClassMethods
|
14
|
+
##
|
15
|
+
# :method: serialized_attributes
|
16
|
+
#
|
17
|
+
# Returns a hash of all the attributes that have been specified for
|
18
|
+
# serialization as keys and their class restriction as values.
|
19
|
+
|
14
20
|
# If you have an attribute that needs to be saved to the database as an
|
15
21
|
# object, and retrieved as the same object, then specify the name of that
|
16
22
|
# attribute using this method and it will be handled automatically. The
|
@@ -44,6 +50,7 @@ module ActiveRecord
|
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
53
|
+
# *DEPRECATED*: Use ActiveRecord::AttributeMethods::Serialization::ClassMethods#serialized_attributes class level method instead.
|
47
54
|
def serialized_attributes
|
48
55
|
message = "Instance level serialized_attributes method is deprecated, please use class level method."
|
49
56
|
ActiveSupport::Deprecation.warn message
|
@@ -86,10 +93,10 @@ module ActiveRecord
|
|
86
93
|
|
87
94
|
# This is only added to the model when serialize is called, which
|
88
95
|
# ensures we do not make things slower when serialization is not used.
|
89
|
-
module Behavior
|
96
|
+
module Behavior # :nodoc:
|
90
97
|
extend ActiveSupport::Concern
|
91
98
|
|
92
|
-
module ClassMethods
|
99
|
+
module ClassMethods # :nodoc:
|
93
100
|
def initialize_attributes(attributes, options = {})
|
94
101
|
serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized
|
95
102
|
super(attributes, options)
|
@@ -62,14 +62,14 @@ module ActiveRecord
|
|
62
62
|
# Note that the model is _not_ yet removed from the database:
|
63
63
|
#
|
64
64
|
# id = post.author.id
|
65
|
-
# Author.
|
65
|
+
# Author.find_by(id: id).nil? # => false
|
66
66
|
#
|
67
67
|
# post.save
|
68
68
|
# post.reload.author # => nil
|
69
69
|
#
|
70
70
|
# Now it _is_ removed from the database:
|
71
71
|
#
|
72
|
-
# Author.
|
72
|
+
# Author.find_by(id: id).nil? # => true
|
73
73
|
#
|
74
74
|
# === One-to-many Example
|
75
75
|
#
|
@@ -113,14 +113,14 @@ module ActiveRecord
|
|
113
113
|
# Note that the model is _not_ yet removed from the database:
|
114
114
|
#
|
115
115
|
# id = post.comments.last.id
|
116
|
-
# Comment.
|
116
|
+
# Comment.find_by(id: id).nil? # => false
|
117
117
|
#
|
118
118
|
# post.save
|
119
119
|
# post.reload.comments.length # => 1
|
120
120
|
#
|
121
121
|
# Now it _is_ removed from the database:
|
122
122
|
#
|
123
|
-
# Comment.
|
123
|
+
# Comment.find_by(id: id).nil? # => true
|
124
124
|
|
125
125
|
module AutosaveAssociation
|
126
126
|
extend ActiveSupport::Concern
|
@@ -212,6 +212,7 @@ module ActiveRecord
|
|
212
212
|
# Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
|
213
213
|
def reload(options = nil)
|
214
214
|
@marked_for_destruction = false
|
215
|
+
@destroyed_by_association = nil
|
215
216
|
super
|
216
217
|
end
|
217
218
|
|
@@ -231,6 +232,19 @@ module ActiveRecord
|
|
231
232
|
@marked_for_destruction
|
232
233
|
end
|
233
234
|
|
235
|
+
# Records the association that is being destroyed and destroying this
|
236
|
+
# record in the process.
|
237
|
+
def destroyed_by_association=(reflection)
|
238
|
+
@destroyed_by_association = reflection
|
239
|
+
end
|
240
|
+
|
241
|
+
# Returns the association for the parent being destroyed.
|
242
|
+
#
|
243
|
+
# Used to avoid updating the counter cache unnecessarily.
|
244
|
+
def destroyed_by_association
|
245
|
+
@destroyed_by_association
|
246
|
+
end
|
247
|
+
|
234
248
|
# Returns whether or not this record has been changed in any way (including whether
|
235
249
|
# any of its nested autosave associations are likewise changed)
|
236
250
|
def changed_for_autosave?
|
@@ -347,7 +361,7 @@ module ActiveRecord
|
|
347
361
|
end
|
348
362
|
|
349
363
|
# reconstruct the scope now that we know the owner's id
|
350
|
-
association.
|
364
|
+
association.reset_scope if association.respond_to?(:reset_scope)
|
351
365
|
end
|
352
366
|
end
|
353
367
|
|
data/lib/active_record/base.rb
CHANGED
@@ -160,10 +160,10 @@ module ActiveRecord #:nodoc:
|
|
160
160
|
#
|
161
161
|
# == Dynamic attribute-based finders
|
162
162
|
#
|
163
|
-
# Dynamic attribute-based finders are a
|
163
|
+
# Dynamic attribute-based finders are a mildly deprecated way of getting (and/or creating) objects
|
164
164
|
# by simple queries without turning to SQL. They work by appending the name of an attribute
|
165
165
|
# to <tt>find_by_</tt> like <tt>Person.find_by_user_name</tt>.
|
166
|
-
# Instead of writing <tt>Person.
|
166
|
+
# Instead of writing <tt>Person.find_by(user_name: user_name)</tt>, you can use
|
167
167
|
# <tt>Person.find_by_user_name(user_name)</tt>.
|
168
168
|
#
|
169
169
|
# It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
|
@@ -172,7 +172,7 @@ module ActiveRecord #:nodoc:
|
|
172
172
|
#
|
173
173
|
# It's also possible to use multiple attributes in the same find by separating them with "_and_".
|
174
174
|
#
|
175
|
-
# Person.
|
175
|
+
# Person.find_by(user_name: user_name, password: password)
|
176
176
|
# Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
|
177
177
|
#
|
178
178
|
# It's even possible to call these dynamic finder methods on relations and named scopes.
|
@@ -83,7 +83,7 @@ module ActiveRecord
|
|
83
83
|
#
|
84
84
|
# In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
|
85
85
|
# So, use the callback macros when you want to ensure that a certain callback is called for the entire
|
86
|
-
# hierarchy, and use the regular
|
86
|
+
# hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
|
87
87
|
# to decide whether they want to call +super+ and trigger the inherited callbacks.
|
88
88
|
#
|
89
89
|
# *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
|
@@ -3,7 +3,6 @@ require 'yaml'
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Coders # :nodoc:
|
5
5
|
class YAMLColumn # :nodoc:
|
6
|
-
RESCUE_ERRORS = [ ArgumentError, Psych::SyntaxError ]
|
7
6
|
|
8
7
|
attr_accessor :object_class
|
9
8
|
|
@@ -24,19 +23,15 @@ module ActiveRecord
|
|
24
23
|
def load(yaml)
|
25
24
|
return object_class.new if object_class != Object && yaml.nil?
|
26
25
|
return yaml unless yaml.is_a?(String) && yaml =~ /^---/
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
|
33
|
-
end
|
34
|
-
obj ||= object_class.new if object_class != Object
|
35
|
-
|
36
|
-
obj
|
37
|
-
rescue *RESCUE_ERRORS
|
38
|
-
yaml
|
26
|
+
obj = YAML.load(yaml)
|
27
|
+
|
28
|
+
unless obj.is_a?(object_class) || obj.nil?
|
29
|
+
raise SerializationTypeMismatch,
|
30
|
+
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
|
39
31
|
end
|
32
|
+
obj ||= object_class.new if object_class != Object
|
33
|
+
|
34
|
+
obj
|
40
35
|
end
|
41
36
|
end
|
42
37
|
end
|
@@ -253,14 +253,6 @@ module ActiveRecord
|
|
253
253
|
@available = Queue.new self
|
254
254
|
end
|
255
255
|
|
256
|
-
# Hack for tests to be able to add connections. Do not call outside of tests
|
257
|
-
def insert_connection_for_test!(c) #:nodoc:
|
258
|
-
synchronize do
|
259
|
-
@connections << c
|
260
|
-
@available.add c
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
256
|
# Retrieve the connection associated with the current thread, or call
|
265
257
|
# #checkout to obtain one if necessary.
|
266
258
|
#
|
@@ -406,7 +398,9 @@ module ActiveRecord
|
|
406
398
|
synchronize do
|
407
399
|
stale = Time.now - @dead_connection_timeout
|
408
400
|
connections.dup.each do |conn|
|
409
|
-
|
401
|
+
if conn.in_use? && stale > conn.last_use && !conn.active?
|
402
|
+
remove conn
|
403
|
+
end
|
410
404
|
end
|
411
405
|
end
|
412
406
|
end
|
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
# limit is enforced by rails and Is less than or equal to
|
22
22
|
# <tt>index_name_length</tt>. The gap between
|
23
23
|
# <tt>index_name_length</tt> is to allow internal rails
|
24
|
-
#
|
24
|
+
# operations to use prefixes in temporary operations.
|
25
25
|
def allowed_index_name_length
|
26
26
|
index_name_length
|
27
27
|
end
|
@@ -125,7 +125,8 @@ module ActiveRecord
|
|
125
125
|
# In order to get around this problem, #transaction will emulate the effect
|
126
126
|
# of nested transactions, by using savepoints:
|
127
127
|
# http://dev.mysql.com/doc/refman/5.0/en/savepoint.html
|
128
|
-
# Savepoints are supported by MySQL and PostgreSQL
|
128
|
+
# Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
|
129
|
+
# supports savepoints.
|
129
130
|
#
|
130
131
|
# It is safe to call this method if a database transaction is already open,
|
131
132
|
# i.e. if #transaction is called within another #transaction block. In case
|
@@ -25,19 +25,13 @@ module ActiveRecord
|
|
25
25
|
when true, false
|
26
26
|
if column && column.type == :integer
|
27
27
|
value ? '1' : '0'
|
28
|
-
elsif column && [:text, :string, :binary].include?(column.type)
|
29
|
-
value ? "'1'" : "'0'"
|
30
28
|
else
|
31
29
|
value ? quoted_true : quoted_false
|
32
30
|
end
|
33
31
|
# BigDecimals need to be put in a non-normalized form and quoted.
|
34
32
|
when nil then "NULL"
|
35
|
-
when
|
36
|
-
|
37
|
-
if column && ![:integer, :float, :decimal].include?(column.type)
|
38
|
-
value = "'#{value}'"
|
39
|
-
end
|
40
|
-
value
|
33
|
+
when BigDecimal then value.to_s('F')
|
34
|
+
when Numeric, ActiveSupport::Duration then value.to_s
|
41
35
|
when Date, Time then "'#{quoted_date(value)}'"
|
42
36
|
when Symbol then "'#{quote_string(value.to_s)}'"
|
43
37
|
when Class then "'#{value.to_s}'"
|
@@ -8,44 +8,28 @@ module ActiveRecord
|
|
8
8
|
# Abstract representation of an index definition on a table. Instances of
|
9
9
|
# this type are typically created and returned by methods in database
|
10
10
|
# adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
|
11
|
-
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where) #:nodoc:
|
11
|
+
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using) #:nodoc:
|
12
12
|
end
|
13
13
|
|
14
14
|
# Abstract representation of a column definition. Instances of this type
|
15
15
|
# are typically created by methods in TableDefinition, and added to the
|
16
16
|
# +columns+ attribute of said TableDefinition object, in order to be used
|
17
17
|
# for generating a number of table creation or table changing SQL statements.
|
18
|
-
class ColumnDefinition < Struct.new(:
|
19
|
-
|
18
|
+
class ColumnDefinition < Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :primary_key) #:nodoc:
|
20
19
|
def string_to_binary(value)
|
21
20
|
value
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_sql
|
29
|
-
column_sql = "#{base.quote_column_name(name)} #{sql_type}"
|
30
|
-
column_options = {}
|
31
|
-
column_options[:null] = null unless null.nil?
|
32
|
-
column_options[:default] = default unless default.nil?
|
33
|
-
add_column_options!(column_sql, column_options) unless type.to_sym == :primary_key
|
34
|
-
column_sql
|
23
|
+
def primary_key?
|
24
|
+
primary_key || type.to_sym == :primary_key
|
35
25
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def add_column_options!(sql, options)
|
40
|
-
base.add_column_options!(sql, options.merge(:column => self))
|
41
|
-
end
|
42
26
|
end
|
43
27
|
|
44
28
|
# Represents the schema of an SQL table in an abstract way. This class
|
45
29
|
# provides methods for manipulating the schema representation.
|
46
30
|
#
|
47
|
-
# Inside migration files, the +t+ object in +create_table+
|
48
|
-
#
|
31
|
+
# Inside migration files, the +t+ object in +create_table+
|
32
|
+
# is actually of this type:
|
49
33
|
#
|
50
34
|
# class SomeMigration < ActiveRecord::Migration
|
51
35
|
# def up
|
@@ -64,28 +48,25 @@ module ActiveRecord
|
|
64
48
|
class TableDefinition
|
65
49
|
# An array of ColumnDefinition objects, representing the column changes
|
66
50
|
# that have been defined.
|
67
|
-
attr_accessor :
|
51
|
+
attr_accessor :indexes
|
52
|
+
attr_reader :name, :temporary, :options
|
68
53
|
|
69
|
-
def initialize(
|
70
|
-
@columns = []
|
54
|
+
def initialize(types, name, temporary, options)
|
71
55
|
@columns_hash = {}
|
72
56
|
@indexes = {}
|
73
|
-
@
|
57
|
+
@native = types
|
58
|
+
@temporary = temporary
|
59
|
+
@options = options
|
60
|
+
@name = name
|
74
61
|
end
|
75
62
|
|
76
|
-
def
|
77
|
-
raise NotImplementedError unless %w{
|
78
|
-
sqlite mysql mysql2
|
79
|
-
}.include? @base.adapter_name.downcase
|
80
|
-
|
81
|
-
options = args.extract_options!
|
82
|
-
column(args[0], :text, options)
|
83
|
-
end
|
63
|
+
def columns; @columns_hash.values; end
|
84
64
|
|
85
65
|
# Appends a primary key definition to the table definition.
|
86
66
|
# Can be called multiple times, but this is probably not a good idea.
|
87
|
-
def primary_key(name)
|
88
|
-
|
67
|
+
def primary_key(name, type = :primary_key, options = {})
|
68
|
+
options[:primary_key] = true
|
69
|
+
column(name, type, options)
|
89
70
|
end
|
90
71
|
|
91
72
|
# Returns a ColumnDefinition for the column with name +name+.
|
@@ -238,20 +219,14 @@ module ActiveRecord
|
|
238
219
|
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
239
220
|
end
|
240
221
|
|
241
|
-
|
242
|
-
|
243
|
-
limit = options.fetch(:limit) do
|
244
|
-
native[type][:limit] if native[type].is_a?(Hash)
|
245
|
-
end
|
246
|
-
|
247
|
-
column.limit = limit
|
248
|
-
column.precision = options[:precision]
|
249
|
-
column.scale = options[:scale]
|
250
|
-
column.default = options[:default]
|
251
|
-
column.null = options[:null]
|
222
|
+
@columns_hash[name] = new_column_definition(name, type, options)
|
252
223
|
self
|
253
224
|
end
|
254
225
|
|
226
|
+
def remove_column(name)
|
227
|
+
@columns_hash.delete name.to_s
|
228
|
+
end
|
229
|
+
|
255
230
|
[:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
|
256
231
|
define_method column_type do |*args|
|
257
232
|
options = args.extract_options!
|
@@ -283,33 +258,57 @@ module ActiveRecord
|
|
283
258
|
args.each do |col|
|
284
259
|
column("#{col}_id", :integer, options)
|
285
260
|
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 :
|
261
|
+
index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
287
262
|
end
|
288
263
|
end
|
289
264
|
alias :belongs_to :references
|
290
265
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
266
|
+
def new_column_definition(name, type, options) # :nodoc:
|
267
|
+
column = create_column_definition name, type
|
268
|
+
limit = options.fetch(:limit) do
|
269
|
+
native[type][:limit] if native[type].is_a?(Hash)
|
270
|
+
end
|
271
|
+
|
272
|
+
column.limit = limit
|
273
|
+
column.precision = options[:precision]
|
274
|
+
column.scale = options[:scale]
|
275
|
+
column.default = options[:default]
|
276
|
+
column.null = options[:null]
|
277
|
+
column.first = options[:first]
|
278
|
+
column.after = options[:after]
|
279
|
+
column.primary_key = type == :primary_key || options[:primary_key]
|
280
|
+
column
|
296
281
|
end
|
297
282
|
|
298
283
|
private
|
299
|
-
def
|
300
|
-
|
301
|
-
@columns << definition
|
302
|
-
@columns_hash[name] = definition
|
303
|
-
definition
|
284
|
+
def create_column_definition(name, type)
|
285
|
+
ColumnDefinition.new name, type
|
304
286
|
end
|
305
287
|
|
306
288
|
def primary_key_column_name
|
307
|
-
primary_key_column = columns.detect { |c| c.
|
289
|
+
primary_key_column = columns.detect { |c| c.primary_key? }
|
308
290
|
primary_key_column && primary_key_column.name
|
309
291
|
end
|
310
292
|
|
311
293
|
def native
|
312
|
-
@
|
294
|
+
@native
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class AlterTable # :nodoc:
|
299
|
+
attr_reader :adds
|
300
|
+
|
301
|
+
def initialize(td)
|
302
|
+
@td = td
|
303
|
+
@adds = []
|
304
|
+
end
|
305
|
+
|
306
|
+
def name; @td.name; end
|
307
|
+
|
308
|
+
def add_column(name, type, options)
|
309
|
+
name = name.to_s
|
310
|
+
type = type.to_sym
|
311
|
+
@adds << @td.new_column_definition(name, type, options)
|
313
312
|
end
|
314
313
|
end
|
315
314
|
|
@@ -489,7 +488,7 @@ module ActiveRecord
|
|
489
488
|
args.each do |name|
|
490
489
|
@base.add_column(@table_name, name, column_type, options)
|
491
490
|
end
|
492
|
-
end
|
491
|
+
end
|
493
492
|
end
|
494
493
|
|
495
494
|
private
|