activerecord 5.0.0.1 → 5.0.1.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 +196 -2
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/association_relation.rb +4 -1
- data/lib/active_record/associations.rb +5 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +4 -2
- data/lib/active_record/associations/builder/singular_association.rb +10 -1
- data/lib/active_record/associations/collection_association.rb +22 -17
- data/lib/active_record/associations/collection_proxy.rb +20 -7
- data/lib/active_record/associations/has_many_through_association.rb +4 -0
- data/lib/active_record/associations/join_dependency.rb +10 -4
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader/association.rb +18 -4
- data/lib/active_record/associations/preloader/collection_association.rb +0 -1
- data/lib/active_record/associations/preloader/singular_association.rb +0 -1
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/attribute.rb +3 -3
- data/lib/active_record/attribute_methods.rb +3 -7
- data/lib/active_record/attribute_methods/primary_key.rb +14 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_set.rb +2 -0
- data/lib/active_record/attribute_set/builder.rb +29 -7
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +15 -11
- data/lib/active_record/base.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +40 -32
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +37 -33
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -5
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +42 -45
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +6 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -5
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +7 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +6 -2
- data/lib/active_record/core.rb +3 -1
- data/lib/active_record/enum.rb +6 -5
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/integration.rb +13 -10
- data/lib/active_record/migration.rb +6 -5
- data/lib/active_record/model_schema.rb +134 -47
- data/lib/active_record/no_touching.rb +4 -0
- data/lib/active_record/persistence.rb +10 -4
- data/lib/active_record/query_cache.rb +13 -15
- data/lib/active_record/querying.rb +3 -3
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/reflection.rb +8 -0
- data/lib/active_record/relation.rb +7 -4
- data/lib/active_record/relation/calculations.rb +11 -11
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +11 -9
- data/lib/active_record/relation/query_methods.rb +3 -3
- data/lib/active_record/result.rb +7 -1
- data/lib/active_record/sanitization.rb +11 -1
- data/lib/active_record/schema_dumper.rb +10 -17
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/table_metadata.rb +4 -3
- data/lib/active_record/touch_later.rb +6 -1
- data/lib/active_record/type/internal/abstract_json.rb +5 -1
- data/lib/active_record/validations/uniqueness.rb +3 -4
- metadata +9 -10
@@ -13,19 +13,6 @@ module ActiveRecord
|
|
13
13
|
result
|
14
14
|
end
|
15
15
|
|
16
|
-
# Returns a record hash with the column names as keys and column values
|
17
|
-
# as values.
|
18
|
-
def select_one(arel, name = nil, binds = [])
|
19
|
-
arel, binds = binds_from_relation(arel, binds)
|
20
|
-
@connection.query_options.merge!(as: :hash)
|
21
|
-
select_result(to_sql(arel, binds), name, binds) do |result|
|
22
|
-
@connection.next_result while @connection.more_results?
|
23
|
-
result.first
|
24
|
-
end
|
25
|
-
ensure
|
26
|
-
@connection.query_options.merge!(as: :array)
|
27
|
-
end
|
28
|
-
|
29
16
|
# Returns an array of arrays containing the field values.
|
30
17
|
# Order is the same as that returned by +columns+.
|
31
18
|
def select_rows(sql, name = nil, binds = [])
|
@@ -37,11 +24,9 @@ module ActiveRecord
|
|
37
24
|
|
38
25
|
# Executes the SQL statement in the context of this connection.
|
39
26
|
def execute(sql, name = nil)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
44
|
-
end
|
27
|
+
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
28
|
+
# made since we established the connection
|
29
|
+
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
45
30
|
|
46
31
|
super
|
47
32
|
end
|
@@ -84,11 +69,9 @@ module ActiveRecord
|
|
84
69
|
end
|
85
70
|
|
86
71
|
def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
91
|
-
end
|
72
|
+
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
73
|
+
# made since we established the connection
|
74
|
+
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
92
75
|
|
93
76
|
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
|
94
77
|
|
@@ -2,7 +2,7 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
module MySQL
|
4
4
|
module Quoting # :nodoc:
|
5
|
-
QUOTED_TRUE, QUOTED_FALSE = '1', '0'
|
5
|
+
QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
|
6
6
|
|
7
7
|
def quote_column_name(name)
|
8
8
|
@quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
|
@@ -90,7 +90,6 @@ module ActiveRecord
|
|
90
90
|
#++
|
91
91
|
|
92
92
|
def active?
|
93
|
-
return false unless @connection
|
94
93
|
@connection.ping
|
95
94
|
end
|
96
95
|
|
@@ -105,10 +104,7 @@ module ActiveRecord
|
|
105
104
|
# Otherwise, this method does nothing.
|
106
105
|
def disconnect!
|
107
106
|
super
|
108
|
-
|
109
|
-
@connection.close
|
110
|
-
@connection = nil
|
111
|
-
end
|
107
|
+
@connection.close
|
112
108
|
end
|
113
109
|
|
114
110
|
private
|
@@ -124,6 +124,8 @@ module ActiveRecord
|
|
124
124
|
pk = primary_key(table_ref) if table_ref
|
125
125
|
end
|
126
126
|
|
127
|
+
pk = suppress_composite_primary_key(pk)
|
128
|
+
|
127
129
|
if pk && use_insert_returning?
|
128
130
|
sql = "#{sql} RETURNING #{quote_column_name(pk)}"
|
129
131
|
end
|
@@ -164,6 +166,12 @@ module ActiveRecord
|
|
164
166
|
def exec_rollback_db_transaction
|
165
167
|
execute "ROLLBACK"
|
166
168
|
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def suppress_composite_primary_key(pk)
|
173
|
+
pk unless pk.is_a?(Array)
|
174
|
+
end
|
167
175
|
end
|
168
176
|
end
|
169
177
|
end
|
@@ -33,7 +33,11 @@ module ActiveRecord
|
|
33
33
|
|
34
34
|
def serialize(value)
|
35
35
|
if value.is_a?(::Array)
|
36
|
-
@pg_encoder.encode(type_cast_array(value, :serialize))
|
36
|
+
result = @pg_encoder.encode(type_cast_array(value, :serialize))
|
37
|
+
if encoding = determine_encoding_of_strings(value)
|
38
|
+
result.force_encoding(encoding)
|
39
|
+
end
|
40
|
+
result
|
37
41
|
else
|
38
42
|
super
|
39
43
|
end
|
@@ -63,6 +67,13 @@ module ActiveRecord
|
|
63
67
|
@subtype.public_send(method, value)
|
64
68
|
end
|
65
69
|
end
|
70
|
+
|
71
|
+
def determine_encoding_of_strings(value)
|
72
|
+
case value
|
73
|
+
when ::Array then determine_encoding_of_strings(value.first)
|
74
|
+
when ::String then value.encoding
|
75
|
+
end
|
76
|
+
end
|
66
77
|
end
|
67
78
|
end
|
68
79
|
end
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
:bit
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def cast_value(value)
|
11
11
|
if ::String === value
|
12
12
|
case value
|
13
13
|
when /^0x/i
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
value # Bit-string notation
|
17
17
|
end
|
18
18
|
else
|
19
|
-
value
|
19
|
+
value.to_s
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -238,6 +238,12 @@ module ActiveRecord
|
|
238
238
|
PostgreSQLColumn.new(*args)
|
239
239
|
end
|
240
240
|
|
241
|
+
def table_options(table_name) # :nodoc:
|
242
|
+
if comment = table_comment(table_name)
|
243
|
+
{ comment: comment }
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
241
247
|
# Returns a comment stored in database for given table
|
242
248
|
def table_comment(table_name) # :nodoc:
|
243
249
|
name = Utils.extract_schema_qualified_name(table_name.to_s)
|
@@ -579,7 +585,7 @@ module ActiveRecord
|
|
579
585
|
end
|
580
586
|
|
581
587
|
def foreign_keys(table_name)
|
582
|
-
fk_info = select_all
|
588
|
+
fk_info = select_all(<<-SQL.strip_heredoc, 'SCHEMA')
|
583
589
|
SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
|
584
590
|
FROM pg_constraint c
|
585
591
|
JOIN pg_class t1 ON c.conrelid = t1.oid
|
@@ -764,11 +764,15 @@ module ActiveRecord
|
|
764
764
|
@case_insensitive_cache[column.sql_type] ||= begin
|
765
765
|
sql = <<-end_sql
|
766
766
|
SELECT exists(
|
767
|
+
SELECT * FROM pg_proc
|
768
|
+
WHERE proname = 'lower'
|
769
|
+
AND proargtypes = ARRAY[#{quote column.sql_type}::regtype]::oidvector
|
770
|
+
) OR exists(
|
767
771
|
SELECT * FROM pg_proc
|
768
772
|
INNER JOIN pg_cast
|
769
|
-
ON casttarget::
|
773
|
+
ON ARRAY[casttarget]::oidvector = proargtypes
|
770
774
|
WHERE proname = 'lower'
|
771
|
-
AND castsource =
|
775
|
+
AND castsource = #{quote column.sql_type}::regtype
|
772
776
|
)
|
773
777
|
end_sql
|
774
778
|
execute_and_clear(sql, "SCHEMA", []) do |result|
|
data/lib/active_record/core.rb
CHANGED
@@ -310,8 +310,8 @@ module ActiveRecord
|
|
310
310
|
# # Instantiates a single new object
|
311
311
|
# User.new(first_name: 'Jamie')
|
312
312
|
def initialize(attributes = nil)
|
313
|
-
@attributes = self.class._default_attributes.deep_dup
|
314
313
|
self.class.define_attribute_methods
|
314
|
+
@attributes = self.class._default_attributes.deep_dup
|
315
315
|
|
316
316
|
init_internals
|
317
317
|
initialize_internals_callback
|
@@ -346,6 +346,8 @@ module ActiveRecord
|
|
346
346
|
|
347
347
|
self.class.define_attribute_methods
|
348
348
|
|
349
|
+
yield self if block_given?
|
350
|
+
|
349
351
|
_run_find_callbacks
|
350
352
|
_run_initialize_callbacks
|
351
353
|
|
data/lib/active_record/enum.rb
CHANGED
@@ -159,8 +159,9 @@ module ActiveRecord
|
|
159
159
|
detect_enum_conflict!(name, name)
|
160
160
|
detect_enum_conflict!(name, "#{name}=")
|
161
161
|
|
162
|
-
|
163
|
-
|
162
|
+
attr = attribute_alias?(name) ? attribute_alias(name) : name
|
163
|
+
decorate_attribute_type(attr, :enum) do |subtype|
|
164
|
+
EnumType.new(attr, enum_values, subtype)
|
164
165
|
end
|
165
166
|
|
166
167
|
_enum_methods_module.module_eval do
|
@@ -182,15 +183,15 @@ module ActiveRecord
|
|
182
183
|
|
183
184
|
# def active?() status == 0 end
|
184
185
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
|
185
|
-
define_method("#{value_method_name}?") { self[
|
186
|
+
define_method("#{value_method_name}?") { self[attr] == value.to_s }
|
186
187
|
|
187
188
|
# def active!() update! status: :active end
|
188
189
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
|
189
|
-
define_method("#{value_method_name}!") { update!
|
190
|
+
define_method("#{value_method_name}!") { update!(attr => value) }
|
190
191
|
|
191
192
|
# scope :active, -> { where status: 0 }
|
192
193
|
klass.send(:detect_enum_conflict!, name, value_method_name, true)
|
193
|
-
klass.scope value_method_name, -> { where(
|
194
|
+
klass.scope value_method_name, -> { where(attr => value) }
|
194
195
|
end
|
195
196
|
end
|
196
197
|
defined_enums[name.to_s] = enum_values
|
@@ -53,18 +53,21 @@ module ActiveRecord
|
|
53
53
|
#
|
54
54
|
# Person.find(5).cache_key(:updated_at, :last_reviewed_at)
|
55
55
|
def cache_key(*timestamp_names)
|
56
|
-
|
57
|
-
when new_record?
|
56
|
+
if new_record?
|
58
57
|
"#{model_name.cache_key}/new"
|
59
|
-
when timestamp_names.any?
|
60
|
-
timestamp = max_updated_column_timestamp(timestamp_names)
|
61
|
-
timestamp = timestamp.utc.to_s(cache_timestamp_format)
|
62
|
-
"#{model_name.cache_key}/#{id}-#{timestamp}"
|
63
|
-
when timestamp = max_updated_column_timestamp
|
64
|
-
timestamp = timestamp.utc.to_s(cache_timestamp_format)
|
65
|
-
"#{model_name.cache_key}/#{id}-#{timestamp}"
|
66
58
|
else
|
67
|
-
|
59
|
+
timestamp = if timestamp_names.any?
|
60
|
+
max_updated_column_timestamp(timestamp_names)
|
61
|
+
else
|
62
|
+
max_updated_column_timestamp
|
63
|
+
end
|
64
|
+
|
65
|
+
if timestamp
|
66
|
+
timestamp = timestamp.utc.to_s(cache_timestamp_format)
|
67
|
+
"#{model_name.cache_key}/#{id}-#{timestamp}"
|
68
|
+
else
|
69
|
+
"#{model_name.cache_key}/#{id}"
|
70
|
+
end
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require "set"
|
2
|
+
require "zlib"
|
1
3
|
require "active_support/core_ext/module/attribute_accessors"
|
2
|
-
require 'set'
|
3
4
|
|
4
5
|
module ActiveRecord
|
5
6
|
class MigrationError < ActiveRecordError#:nodoc:
|
@@ -126,9 +127,9 @@ module ActiveRecord
|
|
126
127
|
class PendingMigrationError < MigrationError#:nodoc:
|
127
128
|
def initialize(message = nil)
|
128
129
|
if !message && defined?(Rails.env)
|
129
|
-
super("Migrations are pending. To resolve this issue, run:\n\n
|
130
|
+
super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate RAILS_ENV=#{::Rails.env}")
|
130
131
|
elsif !message
|
131
|
-
super("Migrations are pending. To resolve this issue, run:\n\n
|
132
|
+
super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate")
|
132
133
|
else
|
133
134
|
super
|
134
135
|
end
|
@@ -145,7 +146,7 @@ module ActiveRecord
|
|
145
146
|
|
146
147
|
class NoEnvironmentInSchemaError < MigrationError #:nodoc:
|
147
148
|
def initialize
|
148
|
-
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n
|
149
|
+
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
|
149
150
|
if defined?(Rails.env)
|
150
151
|
super("#{msg} RAILS_ENV=#{::Rails.env}")
|
151
152
|
else
|
@@ -168,7 +169,7 @@ module ActiveRecord
|
|
168
169
|
msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
|
169
170
|
msg << "You are running in `#{ current }` environment. "
|
170
171
|
msg << "If you are sure you want to continue, first set the environment using:\n\n"
|
171
|
-
msg << "
|
172
|
+
msg << " bin/rails db:environment:set"
|
172
173
|
if defined?(Rails.env)
|
173
174
|
super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
|
174
175
|
else
|
@@ -2,71 +2,150 @@ module ActiveRecord
|
|
2
2
|
module ModelSchema
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
+
##
|
6
|
+
# :singleton-method: primary_key_prefix_type
|
7
|
+
# :call-seq: primary_key_prefix_type
|
8
|
+
#
|
9
|
+
# The prefix type that will be prepended to every primary key column name.
|
10
|
+
# The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
|
11
|
+
# the Product class will look for "productid" instead of "id" as the primary column. If the
|
12
|
+
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
|
13
|
+
# that this is a global setting for all Active Records.
|
14
|
+
|
15
|
+
##
|
16
|
+
# :singleton-method: primary_key_prefix_type=
|
17
|
+
# :call-seq: primary_key_prefix_type=(prefix_type)
|
18
|
+
#
|
19
|
+
# Sets the prefix type that will be prepended to every primary key column name.
|
20
|
+
# The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
|
21
|
+
# the Product class will look for "productid" instead of "id" as the primary column. If the
|
22
|
+
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
|
23
|
+
# that this is a global setting for all Active Records.
|
24
|
+
|
25
|
+
##
|
26
|
+
# :singleton-method: table_name_prefix
|
27
|
+
# :call-seq: table_name_prefix
|
28
|
+
#
|
29
|
+
# The prefix string to prepend to every table name.
|
30
|
+
|
31
|
+
##
|
32
|
+
# :singleton-method: table_name_prefix=
|
33
|
+
# :call-seq: table_name_prefix=(prefix)
|
34
|
+
#
|
35
|
+
# Sets the prefix string to prepend to every table name. So if set to "basecamp_", all table
|
36
|
+
# names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient
|
37
|
+
# way of creating a namespace for tables in a shared database. By default, the prefix is the
|
38
|
+
# empty string.
|
39
|
+
#
|
40
|
+
# If you are organising your models within modules you can add a prefix to the models within
|
41
|
+
# a namespace by defining a singleton method in the parent module called table_name_prefix which
|
42
|
+
# returns your chosen prefix.
|
43
|
+
|
44
|
+
##
|
45
|
+
# :singleton-method: table_name_suffix
|
46
|
+
# :call-seq: table_name_suffix
|
47
|
+
#
|
48
|
+
# The suffix string to append to every table name.
|
49
|
+
|
50
|
+
##
|
51
|
+
# :singleton-method: table_name_suffix=
|
52
|
+
# :call-seq: table_name_suffix=(suffix)
|
53
|
+
#
|
54
|
+
# Works like +table_name_prefix=+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
|
55
|
+
# "people_basecamp"). By default, the suffix is the empty string.
|
56
|
+
#
|
57
|
+
# If you are organising your models within modules, you can add a suffix to the models within
|
58
|
+
# a namespace by defining a singleton method in the parent module called table_name_suffix which
|
59
|
+
# returns your chosen suffix.
|
60
|
+
|
61
|
+
##
|
62
|
+
# :singleton-method: schema_migrations_table_name
|
63
|
+
# :call-seq: schema_migrations_table_name
|
64
|
+
#
|
65
|
+
# The name of the schema migrations table. By default, the value is <tt>"schema_migrations"</tt>.
|
66
|
+
|
67
|
+
##
|
68
|
+
# :singleton-method: schema_migrations_table_name=
|
69
|
+
# :call-seq: schema_migrations_table_name=(table_name)
|
70
|
+
#
|
71
|
+
# Sets the name of the schema migrations table.
|
72
|
+
|
73
|
+
##
|
74
|
+
# :singleton-method: internal_metadata_table_name
|
75
|
+
# :call-seq: internal_metadata_table_name
|
76
|
+
#
|
77
|
+
# The name of the internal metadata table. By default, the value is <tt>"ar_internal_metadata"</tt>.
|
78
|
+
|
79
|
+
##
|
80
|
+
# :singleton-method: internal_metadata_table_name=
|
81
|
+
# :call-seq: internal_metadata_table_name=(table_name)
|
82
|
+
#
|
83
|
+
# Sets the name of the internal metadata table.
|
84
|
+
|
85
|
+
##
|
86
|
+
# :singleton-method: protected_environments
|
87
|
+
# :call-seq: protected_environments
|
88
|
+
#
|
89
|
+
# The array of names of environments where destructive actions should be prohibited. By default,
|
90
|
+
# the value is <tt>["production"]</tt>.
|
91
|
+
|
92
|
+
##
|
93
|
+
# :singleton-method: protected_environments=
|
94
|
+
# :call-seq: protected_environments=(environments)
|
95
|
+
#
|
96
|
+
# Sets an array of names of environments where destructive actions should be prohibited.
|
97
|
+
|
98
|
+
##
|
99
|
+
# :singleton-method: pluralize_table_names
|
100
|
+
# :call-seq: pluralize_table_names
|
101
|
+
#
|
102
|
+
# Indicates whether table names should be the pluralized versions of the corresponding class names.
|
103
|
+
# If true, the default table name for a Product class will be "products". If false, it would just be "product".
|
104
|
+
# See table_name for the full rules on table/class naming. This is true, by default.
|
105
|
+
|
106
|
+
##
|
107
|
+
# :singleton-method: pluralize_table_names=
|
108
|
+
# :call-seq: pluralize_table_names=(value)
|
109
|
+
#
|
110
|
+
# Set whether table names should be the pluralized versions of the corresponding class names.
|
111
|
+
# If true, the default table name for a Product class will be "products". If false, it would just be "product".
|
112
|
+
# See table_name for the full rules on table/class naming. This is true, by default.
|
113
|
+
|
114
|
+
##
|
115
|
+
# :singleton-method: ignored_columns
|
116
|
+
# :call-seq: ignored_columns
|
117
|
+
#
|
118
|
+
# The list of columns names the model should ignore. Ignored columns won't have attribute
|
119
|
+
# accessors defined, and won't be referenced in SQL queries.
|
120
|
+
|
121
|
+
##
|
122
|
+
# :singleton-method: ignored_columns=
|
123
|
+
# :call-seq: ignored_columns=(columns)
|
124
|
+
#
|
125
|
+
# Sets the columns names the model should ignore. Ignored columns won't have attribute
|
126
|
+
# accessors defined, and won't be referenced in SQL queries.
|
127
|
+
|
5
128
|
included do
|
6
|
-
##
|
7
|
-
# :singleton-method:
|
8
|
-
# Accessor for the prefix type that will be prepended to every primary key column name.
|
9
|
-
# The options are :table_name and :table_name_with_underscore. If the first is specified,
|
10
|
-
# the Product class will look for "productid" instead of "id" as the primary column. If the
|
11
|
-
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
|
12
|
-
# that this is a global setting for all Active Records.
|
13
129
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
14
130
|
|
15
|
-
##
|
16
|
-
# :singleton-method:
|
17
|
-
# Accessor for the name of the prefix string to prepend to every table name. So if set
|
18
|
-
# to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
|
19
|
-
# etc. This is a convenient way of creating a namespace for tables in a shared database.
|
20
|
-
# By default, the prefix is the empty string.
|
21
|
-
#
|
22
|
-
# If you are organising your models within modules you can add a prefix to the models within
|
23
|
-
# a namespace by defining a singleton method in the parent module called table_name_prefix which
|
24
|
-
# returns your chosen prefix.
|
25
131
|
class_attribute :table_name_prefix, instance_writer: false
|
26
132
|
self.table_name_prefix = ""
|
27
133
|
|
28
|
-
##
|
29
|
-
# :singleton-method:
|
30
|
-
# Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
|
31
|
-
# "people_basecamp"). By default, the suffix is the empty string.
|
32
|
-
#
|
33
|
-
# If you are organising your models within modules, you can add a suffix to the models within
|
34
|
-
# a namespace by defining a singleton method in the parent module called table_name_suffix which
|
35
|
-
# returns your chosen suffix.
|
36
134
|
class_attribute :table_name_suffix, instance_writer: false
|
37
135
|
self.table_name_suffix = ""
|
38
136
|
|
39
|
-
##
|
40
|
-
# :singleton-method:
|
41
|
-
# Accessor for the name of the schema migrations table. By default, the value is "schema_migrations"
|
42
137
|
class_attribute :schema_migrations_table_name, instance_accessor: false
|
43
138
|
self.schema_migrations_table_name = "schema_migrations"
|
44
139
|
|
45
|
-
##
|
46
|
-
# :singleton-method:
|
47
|
-
# Accessor for the name of the internal metadata table. By default, the value is "ar_internal_metadata"
|
48
140
|
class_attribute :internal_metadata_table_name, instance_accessor: false
|
49
141
|
self.internal_metadata_table_name = "ar_internal_metadata"
|
50
142
|
|
51
|
-
##
|
52
|
-
# :singleton-method:
|
53
|
-
# Accessor for an array of names of environments where destructive actions should be prohibited. By default,
|
54
|
-
# the value is ["production"]
|
55
143
|
class_attribute :protected_environments, instance_accessor: false
|
56
144
|
self.protected_environments = ["production"]
|
57
145
|
|
58
|
-
##
|
59
|
-
# :singleton-method:
|
60
|
-
# Indicates whether table names should be the pluralized versions of the corresponding class names.
|
61
|
-
# If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
|
62
|
-
# See table_name for the full rules on table/class naming. This is true, by default.
|
63
146
|
class_attribute :pluralize_table_names, instance_writer: false
|
64
147
|
self.pluralize_table_names = true
|
65
148
|
|
66
|
-
##
|
67
|
-
# :singleton-method:
|
68
|
-
# Accessor for the list of columns names the model should ignore. Ignored columns won't have attribute
|
69
|
-
# accessors defined, and won't be referenced in SQL queries.
|
70
149
|
class_attribute :ignored_columns, instance_accessor: false
|
71
150
|
self.ignored_columns = [].freeze
|
72
151
|
|
@@ -249,7 +328,11 @@ module ActiveRecord
|
|
249
328
|
end
|
250
329
|
|
251
330
|
def attributes_builder # :nodoc:
|
252
|
-
@attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key)
|
331
|
+
@attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key) do |name|
|
332
|
+
unless columns_hash.key?(name)
|
333
|
+
_default_attributes[name].dup
|
334
|
+
end
|
335
|
+
end
|
253
336
|
end
|
254
337
|
|
255
338
|
def columns_hash # :nodoc:
|
@@ -278,8 +361,12 @@ module ActiveRecord
|
|
278
361
|
#
|
279
362
|
# +attr_name+ The name of the attribute to retrieve the type for. Must be
|
280
363
|
# a string
|
281
|
-
def type_for_attribute(attr_name)
|
282
|
-
|
364
|
+
def type_for_attribute(attr_name, &block)
|
365
|
+
if block
|
366
|
+
attribute_types.fetch(attr_name, &block)
|
367
|
+
else
|
368
|
+
attribute_types[attr_name]
|
369
|
+
end
|
283
370
|
end
|
284
371
|
|
285
372
|
# Returns a hash where the keys are column names and the values are
|