activerecord 3.2.22.5 → 4.2.11.3
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1632 -609
- data/MIT-LICENSE +1 -1
- data/README.rdoc +37 -41
- data/examples/performance.rb +31 -19
- data/examples/simple.rb +4 -4
- data/lib/active_record/aggregations.rb +56 -42
- data/lib/active_record/association_relation.rb +35 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -36
- data/lib/active_record/associations/association.rb +73 -55
- data/lib/active_record/associations/association_scope.rb +143 -82
- data/lib/active_record/associations/belongs_to_association.rb +65 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
- data/lib/active_record/associations/builder/association.rb +125 -31
- data/lib/active_record/associations/builder/belongs_to.rb +89 -61
- data/lib/active_record/associations/builder/collection_association.rb +69 -49
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +113 -42
- data/lib/active_record/associations/builder/has_many.rb +8 -64
- data/lib/active_record/associations/builder/has_one.rb +12 -51
- data/lib/active_record/associations/builder/singular_association.rb +23 -17
- data/lib/active_record/associations/collection_association.rb +251 -177
- data/lib/active_record/associations/collection_proxy.rb +963 -63
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +113 -22
- data/lib/active_record/associations/has_many_through_association.rb +99 -39
- data/lib/active_record/associations/has_one_association.rb +43 -20
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +76 -107
- data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
- data/lib/active_record/associations/join_dependency.rb +230 -156
- data/lib/active_record/associations/preloader/association.rb +96 -55
- data/lib/active_record/associations/preloader/collection_association.rb +3 -3
- data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
- data/lib/active_record/associations/preloader/has_one.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +62 -33
- data/lib/active_record/associations/preloader.rb +101 -79
- data/lib/active_record/associations/singular_association.rb +29 -13
- data/lib/active_record/associations/through_association.rb +30 -16
- data/lib/active_record/associations.rb +463 -345
- data/lib/active_record/attribute.rb +163 -0
- data/lib/active_record/attribute_assignment.rb +142 -151
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
- data/lib/active_record/attribute_methods/dirty.rb +137 -57
- data/lib/active_record/attribute_methods/primary_key.rb +50 -36
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +73 -106
- data/lib/active_record/attribute_methods/serialization.rb +44 -94
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +49 -45
- data/lib/active_record/attribute_methods/write.rb +57 -44
- data/lib/active_record/attribute_methods.rb +301 -141
- data/lib/active_record/attribute_set/builder.rb +106 -0
- data/lib/active_record/attribute_set.rb +81 -0
- data/lib/active_record/attributes.rb +147 -0
- data/lib/active_record/autosave_association.rb +246 -217
- data/lib/active_record/base.rb +70 -474
- data/lib/active_record/callbacks.rb +66 -28
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/coders/yaml_column.rb +18 -21
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +396 -219
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -164
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -55
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +261 -169
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +707 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +215 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +298 -89
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +466 -196
- data/lib/active_record/connection_adapters/column.rb +31 -245
- data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +45 -57
- data/lib/active_record/connection_adapters/mysql_adapter.rb +180 -123
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +596 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +430 -999
- data/lib/active_record/connection_adapters/schema_cache.rb +52 -27
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +579 -22
- data/lib/active_record/connection_handling.rb +132 -0
- data/lib/active_record/core.rb +579 -0
- data/lib/active_record/counter_cache.rb +157 -105
- data/lib/active_record/dynamic_matchers.rb +119 -63
- data/lib/active_record/enum.rb +197 -0
- data/lib/active_record/errors.rb +94 -36
- data/lib/active_record/explain.rb +15 -63
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +9 -5
- data/lib/active_record/fixture_set/file.rb +56 -0
- data/lib/active_record/fixtures.rb +302 -215
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +143 -70
- data/lib/active_record/integration.rb +65 -12
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +73 -52
- data/lib/active_record/locking/pessimistic.rb +5 -5
- data/lib/active_record/log_subscriber.rb +24 -21
- data/lib/active_record/migration/command_recorder.rb +124 -32
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/migration.rb +511 -213
- data/lib/active_record/model_schema.rb +91 -117
- data/lib/active_record/nested_attributes.rb +184 -130
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +81 -0
- data/lib/active_record/persistence.rb +276 -117
- data/lib/active_record/query_cache.rb +19 -37
- data/lib/active_record/querying.rb +28 -18
- data/lib/active_record/railtie.rb +73 -40
- data/lib/active_record/railties/console_sandbox.rb +3 -4
- data/lib/active_record/railties/controller_runtime.rb +4 -3
- data/lib/active_record/railties/databases.rake +141 -416
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +1 -4
- data/lib/active_record/reflection.rb +513 -154
- data/lib/active_record/relation/batches.rb +91 -43
- data/lib/active_record/relation/calculations.rb +199 -161
- data/lib/active_record/relation/delegation.rb +116 -25
- data/lib/active_record/relation/finder_methods.rb +362 -248
- data/lib/active_record/relation/merger.rb +193 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
- data/lib/active_record/relation/predicate_builder.rb +135 -43
- data/lib/active_record/relation/query_methods.rb +928 -167
- data/lib/active_record/relation/spawn_methods.rb +48 -149
- data/lib/active_record/relation.rb +352 -207
- data/lib/active_record/result.rb +101 -10
- data/lib/active_record/runtime_registry.rb +22 -0
- data/lib/active_record/sanitization.rb +56 -59
- data/lib/active_record/schema.rb +19 -13
- data/lib/active_record/schema_dumper.rb +106 -63
- data/lib/active_record/schema_migration.rb +53 -0
- data/lib/active_record/scoping/default.rb +50 -57
- data/lib/active_record/scoping/named.rb +73 -109
- data/lib/active_record/scoping.rb +58 -123
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +12 -22
- data/lib/active_record/statement_cache.rb +111 -0
- data/lib/active_record/store.rb +168 -15
- data/lib/active_record/tasks/database_tasks.rb +299 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +159 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +101 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
- data/lib/active_record/timestamp.rb +23 -16
- data/lib/active_record/transactions.rb +125 -79
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/binary.rb +50 -0
- data/lib/active_record/type/boolean.rb +31 -0
- data/lib/active_record/type/date.rb +50 -0
- data/lib/active_record/type/date_time.rb +54 -0
- data/lib/active_record/type/decimal.rb +64 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/decorator.rb +14 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/integer.rb +59 -0
- data/lib/active_record/type/mutable.rb +16 -0
- data/lib/active_record/type/numeric.rb +36 -0
- data/lib/active_record/type/serialized.rb +62 -0
- data/lib/active_record/type/string.rb +40 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +26 -0
- data/lib/active_record/type/time_value.rb +38 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type/value.rb +110 -0
- data/lib/active_record/type.rb +23 -0
- data/lib/active_record/validations/associated.rb +24 -16
- data/lib/active_record/validations/presence.rb +67 -0
- data/lib/active_record/validations/uniqueness.rb +123 -64
- data/lib/active_record/validations.rb +36 -29
- data/lib/active_record/version.rb +5 -7
- data/lib/active_record.rb +66 -46
- data/lib/rails/generators/active_record/migration/migration_generator.rb +53 -8
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +5 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/migration.rb +11 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -4
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- data/lib/rails/generators/active_record.rb +3 -11
- metadata +101 -45
- data/examples/associations.png +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
- data/lib/active_record/associations/join_helper.rb +0 -55
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- 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/active_record/test_case.rb +0 -73
- 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
@@ -17,13 +17,24 @@ module ActiveRecord
|
|
17
17
|
cattr_accessor :ignore_tables
|
18
18
|
@@ignore_tables = []
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
class << self
|
21
|
+
def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
|
22
|
+
new(connection, generate_options(config)).dump(stream)
|
23
|
+
stream
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def generate_options(config)
|
28
|
+
{
|
29
|
+
table_name_prefix: config.table_name_prefix,
|
30
|
+
table_name_suffix: config.table_name_suffix
|
31
|
+
}
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
def dump(stream)
|
26
36
|
header(stream)
|
37
|
+
extensions(stream)
|
27
38
|
tables(stream)
|
28
39
|
trailer(stream)
|
29
40
|
stream
|
@@ -31,14 +42,15 @@ module ActiveRecord
|
|
31
42
|
|
32
43
|
private
|
33
44
|
|
34
|
-
def initialize(connection)
|
45
|
+
def initialize(connection, options = {})
|
35
46
|
@connection = connection
|
36
47
|
@types = @connection.native_database_types
|
37
48
|
@version = Migrator::current_version rescue nil
|
49
|
+
@options = options
|
38
50
|
end
|
39
51
|
|
40
52
|
def header(stream)
|
41
|
-
define_params = @version ? ":
|
53
|
+
define_params = @version ? "version: #{@version}" : ""
|
42
54
|
|
43
55
|
if stream.respond_to?(:external_encoding) && stream.external_encoding
|
44
56
|
stream.puts "# encoding: #{stream.external_encoding.name}"
|
@@ -55,7 +67,7 @@ module ActiveRecord
|
|
55
67
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
56
68
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
57
69
|
#
|
58
|
-
# It's strongly recommended
|
70
|
+
# It's strongly recommended that you check this file into your version control system.
|
59
71
|
|
60
72
|
ActiveRecord::Schema.define(#{define_params}) do
|
61
73
|
|
@@ -66,17 +78,30 @@ HEADER
|
|
66
78
|
stream.puts "end"
|
67
79
|
end
|
68
80
|
|
81
|
+
def extensions(stream)
|
82
|
+
return unless @connection.supports_extensions?
|
83
|
+
extensions = @connection.extensions
|
84
|
+
if extensions.any?
|
85
|
+
stream.puts " # These are extensions that must be enabled in order to support this database"
|
86
|
+
extensions.each do |extension|
|
87
|
+
stream.puts " enable_extension #{extension.inspect}"
|
88
|
+
end
|
89
|
+
stream.puts
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
69
93
|
def tables(stream)
|
70
|
-
@connection.tables.sort
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
94
|
+
sorted_tables = @connection.tables.sort
|
95
|
+
|
96
|
+
sorted_tables.each do |table_name|
|
97
|
+
table(table_name, stream) unless ignored?(table_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
# dump foreign keys at the end to make sure all dependent tables exist.
|
101
|
+
if @connection.supports_foreign_keys?
|
102
|
+
sorted_tables.each do |tbl|
|
103
|
+
foreign_keys(tbl, stream) unless ignored?(tbl)
|
78
104
|
end
|
79
|
-
table(tbl, stream)
|
80
105
|
end
|
81
106
|
end
|
82
107
|
|
@@ -86,51 +111,41 @@ HEADER
|
|
86
111
|
tbl = StringIO.new
|
87
112
|
|
88
113
|
# first dump primary key column
|
89
|
-
|
90
|
-
pk, _ = @connection.pk_and_sequence_for(table)
|
91
|
-
elsif @connection.respond_to?(:primary_key)
|
92
|
-
pk = @connection.primary_key(table)
|
93
|
-
end
|
114
|
+
pk = @connection.primary_key(table)
|
94
115
|
|
95
116
|
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
96
|
-
|
117
|
+
pkcol = columns.detect { |c| c.name == pk }
|
118
|
+
if pkcol
|
97
119
|
if pk != 'id'
|
98
|
-
tbl.print %Q(, :
|
120
|
+
tbl.print %Q(, primary_key: "#{pk}")
|
121
|
+
elsif pkcol.sql_type == 'bigint'
|
122
|
+
tbl.print ", id: :bigserial"
|
123
|
+
elsif pkcol.sql_type == 'uuid'
|
124
|
+
tbl.print ", id: :uuid"
|
125
|
+
tbl.print %Q(, default: #{pkcol.default_function.inspect})
|
99
126
|
end
|
100
127
|
else
|
101
|
-
tbl.print ", :
|
128
|
+
tbl.print ", id: false"
|
102
129
|
end
|
103
|
-
tbl.print ", :
|
130
|
+
tbl.print ", force: :cascade"
|
104
131
|
tbl.puts " do |t|"
|
105
132
|
|
106
133
|
# then dump all non-primary key columns
|
107
134
|
column_specs = columns.map do |column|
|
108
|
-
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'"
|
135
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
109
136
|
next if column.name == pk
|
110
|
-
|
111
|
-
spec[:name] = column.name.inspect
|
112
|
-
|
113
|
-
# AR has an optimization which handles zero-scale decimals as integers. This
|
114
|
-
# code ensures that the dumper still dumps the column as a decimal.
|
115
|
-
spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
|
116
|
-
'decimal'
|
117
|
-
else
|
118
|
-
column.type.to_s
|
119
|
-
end
|
120
|
-
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal'
|
121
|
-
spec[:precision] = column.precision.inspect if column.precision
|
122
|
-
spec[:scale] = column.scale.inspect if column.scale
|
123
|
-
spec[:null] = 'false' unless column.null
|
124
|
-
spec[:default] = default_string(column.default) if column.has_default?
|
125
|
-
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
|
126
|
-
spec
|
137
|
+
@connection.column_spec(column, @types)
|
127
138
|
end.compact
|
128
139
|
|
129
140
|
# find all migration keys used in this table
|
130
|
-
keys =
|
141
|
+
keys = @connection.migration_keys
|
131
142
|
|
132
143
|
# figure out the lengths for each column based on above keys
|
133
|
-
lengths = keys.map{ |key|
|
144
|
+
lengths = keys.map { |key|
|
145
|
+
column_specs.map { |spec|
|
146
|
+
spec[key] ? spec[key].length + 2 : 0
|
147
|
+
}.max
|
148
|
+
}
|
134
149
|
|
135
150
|
# the string we're going to sprintf our values against, with standardized column widths
|
136
151
|
format_string = lengths.map{ |len| "%-#{len}s" }
|
@@ -166,34 +181,26 @@ HEADER
|
|
166
181
|
stream
|
167
182
|
end
|
168
183
|
|
169
|
-
def default_string(value)
|
170
|
-
case value
|
171
|
-
when BigDecimal
|
172
|
-
value.to_s
|
173
|
-
when Date, DateTime, Time
|
174
|
-
"'" + value.to_s(:db) + "'"
|
175
|
-
else
|
176
|
-
value.inspect
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
184
|
def indexes(table, stream)
|
181
185
|
if (indexes = @connection.indexes(table)).any?
|
182
186
|
add_index_statements = indexes.map do |index|
|
183
187
|
statement_parts = [
|
184
|
-
|
188
|
+
"add_index #{remove_prefix_and_suffix(index.table).inspect}",
|
185
189
|
index.columns.inspect,
|
186
|
-
|
190
|
+
"name: #{index.name.inspect}",
|
187
191
|
]
|
188
|
-
statement_parts << ':
|
192
|
+
statement_parts << 'unique: true' if index.unique
|
189
193
|
|
190
194
|
index_lengths = (index.lengths || []).compact
|
191
|
-
statement_parts <<
|
195
|
+
statement_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any?
|
192
196
|
|
193
|
-
index_orders =
|
194
|
-
statement_parts <<
|
197
|
+
index_orders = index.orders || {}
|
198
|
+
statement_parts << "order: #{index.orders.inspect}" if index_orders.any?
|
199
|
+
statement_parts << "where: #{index.where.inspect}" if index.where
|
200
|
+
statement_parts << "using: #{index.using.inspect}" if index.using
|
201
|
+
statement_parts << "type: #{index.type.inspect}" if index.type
|
195
202
|
|
196
|
-
|
203
|
+
" #{statement_parts.join(', ')}"
|
197
204
|
end
|
198
205
|
|
199
206
|
stream.puts add_index_statements.sort.join("\n")
|
@@ -201,8 +208,44 @@ HEADER
|
|
201
208
|
end
|
202
209
|
end
|
203
210
|
|
211
|
+
def foreign_keys(table, stream)
|
212
|
+
if (foreign_keys = @connection.foreign_keys(table)).any?
|
213
|
+
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
214
|
+
parts = [
|
215
|
+
"add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}",
|
216
|
+
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
217
|
+
]
|
218
|
+
|
219
|
+
if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table)
|
220
|
+
parts << "column: #{foreign_key.column.inspect}"
|
221
|
+
end
|
222
|
+
|
223
|
+
if foreign_key.custom_primary_key?
|
224
|
+
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
225
|
+
end
|
226
|
+
|
227
|
+
if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
|
228
|
+
parts << "name: #{foreign_key.name.inspect}"
|
229
|
+
end
|
230
|
+
|
231
|
+
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
232
|
+
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
233
|
+
|
234
|
+
" #{parts.join(', ')}"
|
235
|
+
end
|
236
|
+
|
237
|
+
stream.puts add_foreign_key_statements.sort.join("\n")
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
204
241
|
def remove_prefix_and_suffix(table)
|
205
|
-
table.gsub(/^(#{
|
242
|
+
table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
|
243
|
+
end
|
244
|
+
|
245
|
+
def ignored?(table_name)
|
246
|
+
['schema_migrations', ignore_tables].flatten.any? do |ignored|
|
247
|
+
ignored === remove_prefix_and_suffix(table_name)
|
248
|
+
end
|
206
249
|
end
|
207
250
|
end
|
208
251
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_record/scoping/default'
|
2
|
+
require 'active_record/scoping/named'
|
3
|
+
require 'active_record/base'
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
class SchemaMigration < ActiveRecord::Base
|
7
|
+
class << self
|
8
|
+
def primary_key
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def table_name
|
13
|
+
"#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def index_name
|
17
|
+
"#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def table_exists?
|
21
|
+
connection.table_exists?(table_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_table(limit=nil)
|
25
|
+
unless table_exists?
|
26
|
+
version_options = {null: false}
|
27
|
+
version_options[:limit] = limit if limit
|
28
|
+
|
29
|
+
connection.create_table(table_name, id: false) do |t|
|
30
|
+
t.column :version, :string, version_options
|
31
|
+
end
|
32
|
+
connection.add_index table_name, :version, unique: true, name: index_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def drop_table
|
37
|
+
connection.drop_table table_name if table_exists?
|
38
|
+
end
|
39
|
+
|
40
|
+
def normalize_migration_number(number)
|
41
|
+
"%.3d" % number.to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
def normalized_versions
|
45
|
+
pluck(:version).map { |v| normalize_migration_number v }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def version
|
50
|
+
super.to_i
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,43 +1,35 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module Scoping
|
5
3
|
module Default
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
|
8
6
|
included do
|
9
|
-
# Stores the default scope for the class
|
10
|
-
class_attribute :default_scopes, :
|
7
|
+
# Stores the default scope for the class.
|
8
|
+
class_attribute :default_scopes, instance_writer: false, instance_predicate: false
|
9
|
+
|
11
10
|
self.default_scopes = []
|
12
11
|
end
|
13
12
|
|
14
13
|
module ClassMethods
|
15
|
-
# Returns a scope for the model without the
|
14
|
+
# Returns a scope for the model without the previously set scopes.
|
16
15
|
#
|
17
16
|
# class Post < ActiveRecord::Base
|
18
17
|
# def self.default_scope
|
19
|
-
# where :
|
18
|
+
# where published: true
|
20
19
|
# end
|
21
20
|
# end
|
22
21
|
#
|
23
|
-
# Post.all
|
24
|
-
# Post.unscoped.all
|
22
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
23
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
24
|
+
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
|
25
25
|
#
|
26
26
|
# This method also accepts a block. All queries inside the block will
|
27
|
-
# not use the
|
27
|
+
# not use the previously set scopes.
|
28
28
|
#
|
29
29
|
# Post.unscoped {
|
30
30
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
31
31
|
# }
|
32
|
-
|
33
|
-
# It is recommended to use the block form of unscoped because chaining
|
34
|
-
# unscoped with <tt>scope</tt> does not work. Assuming that
|
35
|
-
# <tt>published</tt> is a <tt>scope</tt>, the following two statements
|
36
|
-
# are equal: the default_scope is applied on both.
|
37
|
-
#
|
38
|
-
# Post.unscoped.published
|
39
|
-
# Post.published
|
40
|
-
def unscoped #:nodoc:
|
32
|
+
def unscoped
|
41
33
|
block_given? ? relation.scoping { yield } : relation
|
42
34
|
end
|
43
35
|
|
@@ -51,81 +43,83 @@ module ActiveRecord
|
|
51
43
|
# the model.
|
52
44
|
#
|
53
45
|
# class Article < ActiveRecord::Base
|
54
|
-
# default_scope where(:
|
46
|
+
# default_scope { where(published: true) }
|
55
47
|
# end
|
56
48
|
#
|
57
49
|
# Article.all # => SELECT * FROM articles WHERE published = true
|
58
50
|
#
|
59
|
-
# The
|
60
|
-
# applied while updating a record.
|
51
|
+
# The +default_scope+ is also applied while creating/building a record.
|
52
|
+
# It is not applied while updating a record.
|
61
53
|
#
|
62
54
|
# Article.new.published # => true
|
63
55
|
# Article.create.published # => true
|
64
56
|
#
|
65
|
-
# You can also
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# default_scope { where(:published_at => Time.now - 1.week) }
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# (You can also pass any object which responds to <tt>call</tt> to the <tt>default_scope</tt>
|
72
|
-
# macro, and it will be called when building the default scope.)
|
57
|
+
# (You can also pass any object which responds to +call+ to the
|
58
|
+
# +default_scope+ macro, and it will be called when building the
|
59
|
+
# default scope.)
|
73
60
|
#
|
74
|
-
# If you use multiple
|
75
|
-
# be merged together:
|
61
|
+
# If you use multiple +default_scope+ declarations in your model then
|
62
|
+
# they will be merged together:
|
76
63
|
#
|
77
64
|
# class Article < ActiveRecord::Base
|
78
|
-
# default_scope where(:
|
79
|
-
# default_scope where(:
|
65
|
+
# default_scope { where(published: true) }
|
66
|
+
# default_scope { where(rating: 'G') }
|
80
67
|
# end
|
81
68
|
#
|
82
69
|
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
83
70
|
#
|
84
|
-
# This is also the case with inheritance and module includes where the
|
85
|
-
# defines a
|
71
|
+
# This is also the case with inheritance and module includes where the
|
72
|
+
# parent or module defines a +default_scope+ and the child or including
|
73
|
+
# class defines a second one.
|
86
74
|
#
|
87
|
-
# If you need to do more complex things with a default scope, you can
|
88
|
-
# define it as a class method:
|
75
|
+
# If you need to do more complex things with a default scope, you can
|
76
|
+
# alternatively define it as a class method:
|
89
77
|
#
|
90
78
|
# class Article < ActiveRecord::Base
|
91
79
|
# def self.default_scope
|
92
80
|
# # Should return a scope, you can call 'super' here etc.
|
93
81
|
# end
|
94
82
|
# end
|
95
|
-
def default_scope(scope =
|
83
|
+
def default_scope(scope = nil)
|
96
84
|
scope = Proc.new if block_given?
|
97
|
-
|
85
|
+
|
86
|
+
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
87
|
+
raise ArgumentError,
|
88
|
+
"Support for calling #default_scope without a block is removed. For example instead " \
|
89
|
+
"of `default_scope where(color: 'red')`, please use " \
|
90
|
+
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
91
|
+
"self.default_scope.)"
|
92
|
+
end
|
93
|
+
|
94
|
+
self.default_scopes += [scope]
|
98
95
|
end
|
99
96
|
|
100
|
-
def build_default_scope
|
101
|
-
if
|
97
|
+
def build_default_scope(base_rel = relation) # :nodoc:
|
98
|
+
return if abstract_class?
|
99
|
+
if !Base.is_a?(method(:default_scope).owner)
|
100
|
+
# The user has defined their own default scope method, so call that
|
102
101
|
evaluate_default_scope { default_scope }
|
103
102
|
elsif default_scopes.any?
|
104
103
|
evaluate_default_scope do
|
105
|
-
default_scopes.inject(
|
106
|
-
|
107
|
-
default_scope.apply_finder_options(scope)
|
108
|
-
elsif !scope.is_a?(Relation) && scope.respond_to?(:call)
|
109
|
-
default_scope.merge(scope.call)
|
110
|
-
else
|
111
|
-
default_scope.merge(scope)
|
112
|
-
end
|
104
|
+
default_scopes.inject(base_rel) do |default_scope, scope|
|
105
|
+
default_scope.merge(base_rel.scoping { scope.call })
|
113
106
|
end
|
114
107
|
end
|
115
108
|
end
|
116
109
|
end
|
117
110
|
|
118
|
-
def ignore_default_scope?
|
119
|
-
|
111
|
+
def ignore_default_scope? # :nodoc:
|
112
|
+
ScopeRegistry.value_for(:ignore_default_scope, self)
|
120
113
|
end
|
121
114
|
|
122
|
-
def ignore_default_scope=(ignore)
|
123
|
-
|
115
|
+
def ignore_default_scope=(ignore) # :nodoc:
|
116
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, self, ignore)
|
124
117
|
end
|
125
118
|
|
126
|
-
# The ignore_default_scope flag is used to prevent an infinite recursion
|
127
|
-
# a default scope references a scope which has a default
|
128
|
-
|
119
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion
|
120
|
+
# situation where a default scope references a scope which has a default
|
121
|
+
# scope which references a scope...
|
122
|
+
def evaluate_default_scope # :nodoc:
|
129
123
|
return if ignore_default_scope?
|
130
124
|
|
131
125
|
begin
|
@@ -135,7 +129,6 @@ module ActiveRecord
|
|
135
129
|
self.ignore_default_scope = false
|
136
130
|
end
|
137
131
|
end
|
138
|
-
|
139
132
|
end
|
140
133
|
end
|
141
134
|
end
|