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,10 +1,8 @@
|
|
1
|
-
require 'active_support/core_ext/array/wrap'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module Validations
|
5
|
-
class UniquenessValidator < ActiveModel::EachValidator
|
3
|
+
class UniquenessValidator < ActiveModel::EachValidator # :nodoc:
|
6
4
|
def initialize(options)
|
7
|
-
super(
|
5
|
+
super({ case_sensitive: true }.merge!(options))
|
8
6
|
end
|
9
7
|
|
10
8
|
# Unfortunately, we have to tie Uniqueness validators to a class.
|
@@ -15,23 +13,19 @@ module ActiveRecord
|
|
15
13
|
def validate_each(record, attribute, value)
|
16
14
|
finder_class = find_finder_class_for(record)
|
17
15
|
table = finder_class.arel_table
|
18
|
-
|
19
|
-
coder = record.class.serialized_attributes[attribute.to_s]
|
20
|
-
|
21
|
-
if value && coder
|
22
|
-
value = coder.dump value
|
23
|
-
end
|
16
|
+
value = deserialize_attribute(record, attribute, value)
|
24
17
|
|
25
18
|
relation = build_relation(finder_class, table, attribute, value)
|
26
|
-
relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.
|
19
|
+
relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
|
20
|
+
relation = scope_relation(record, table, relation)
|
21
|
+
relation = finder_class.unscoped.where(relation)
|
22
|
+
relation.merge!(options[:conditions]) if options[:conditions]
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
24
|
+
if relation.exists?
|
25
|
+
error_options = options.except(:case_sensitive, :scope, :conditions)
|
26
|
+
error_options[:value] = value
|
32
27
|
|
33
|
-
|
34
|
-
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
|
28
|
+
record.errors.add(attribute, :taken, error_options)
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
@@ -46,67 +40,114 @@ module ActiveRecord
|
|
46
40
|
class_hierarchy = [record.class]
|
47
41
|
|
48
42
|
while class_hierarchy.first != @klass
|
49
|
-
class_hierarchy.
|
43
|
+
class_hierarchy.unshift(class_hierarchy.first.superclass)
|
50
44
|
end
|
51
45
|
|
52
46
|
class_hierarchy.detect { |klass| !klass.abstract_class? }
|
53
47
|
end
|
54
48
|
|
55
49
|
def build_relation(klass, table, attribute, value) #:nodoc:
|
50
|
+
if reflection = klass.reflect_on_association(attribute)
|
51
|
+
attribute = reflection.foreign_key
|
52
|
+
value = value.attributes[reflection.primary_key_column.name]
|
53
|
+
end
|
54
|
+
|
56
55
|
column = klass.columns_hash[attribute.to_s]
|
57
|
-
value
|
56
|
+
value = klass.connection.type_cast(value, column)
|
57
|
+
value = value.to_s[0, column.limit] if value && column.limit && column.text?
|
58
58
|
|
59
59
|
if !options[:case_sensitive] && value && column.text?
|
60
60
|
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
|
61
|
-
|
61
|
+
klass.connection.case_insensitive_comparison(table, attribute, column, value)
|
62
62
|
else
|
63
|
-
value
|
64
|
-
|
63
|
+
value = klass.connection.case_sensitive_modifier(value) unless value.nil?
|
64
|
+
table[attribute].eq(value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def scope_relation(record, table, relation)
|
69
|
+
Array(options[:scope]).each do |scope_item|
|
70
|
+
if reflection = record.class.reflect_on_association(scope_item)
|
71
|
+
scope_value = record.send(reflection.foreign_key)
|
72
|
+
scope_item = reflection.foreign_key
|
73
|
+
else
|
74
|
+
scope_value = record.read_attribute(scope_item)
|
75
|
+
end
|
76
|
+
relation = relation.and(table[scope_item].eq(scope_value))
|
65
77
|
end
|
66
78
|
|
67
79
|
relation
|
68
80
|
end
|
81
|
+
|
82
|
+
def deserialize_attribute(record, attribute, value)
|
83
|
+
coder = record.class.serialized_attributes[attribute.to_s]
|
84
|
+
value = coder.dump value if value && coder
|
85
|
+
value
|
86
|
+
end
|
69
87
|
end
|
70
88
|
|
71
89
|
module ClassMethods
|
72
|
-
# Validates whether the value of the specified attributes are unique
|
73
|
-
# Useful for making sure that only one user
|
90
|
+
# Validates whether the value of the specified attributes are unique
|
91
|
+
# across the system. Useful for making sure that only one user
|
74
92
|
# can be named "davidhh".
|
75
93
|
#
|
76
94
|
# class Person < ActiveRecord::Base
|
77
95
|
# validates_uniqueness_of :user_name
|
78
96
|
# end
|
79
97
|
#
|
80
|
-
# It can also validate whether the value of the specified attributes are
|
98
|
+
# It can also validate whether the value of the specified attributes are
|
99
|
+
# unique based on a <tt>:scope</tt> parameter:
|
81
100
|
#
|
82
101
|
# class Person < ActiveRecord::Base
|
83
|
-
# validates_uniqueness_of :user_name, :
|
102
|
+
# validates_uniqueness_of :user_name, scope: :account_id
|
84
103
|
# end
|
85
104
|
#
|
86
|
-
# Or even multiple scope parameters. For example, making sure that a
|
87
|
-
# per semester for a particular
|
105
|
+
# Or even multiple scope parameters. For example, making sure that a
|
106
|
+
# teacher can only be on the schedule once per semester for a particular
|
107
|
+
# class.
|
88
108
|
#
|
89
109
|
# class TeacherSchedule < ActiveRecord::Base
|
90
|
-
# validates_uniqueness_of :teacher_id, :
|
110
|
+
# validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
|
91
111
|
# end
|
92
112
|
#
|
93
|
-
#
|
94
|
-
#
|
113
|
+
# It is also possible to limit the uniqueness constraint to a set of
|
114
|
+
# records matching certain conditions. In this example archived articles
|
115
|
+
# are not being taken into consideration when validating uniqueness
|
116
|
+
# of the title attribute:
|
117
|
+
#
|
118
|
+
# class Article < ActiveRecord::Base
|
119
|
+
# validates_uniqueness_of :title, conditions: where('status != ?', 'archived')
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# When the record is created, a check is performed to make sure that no
|
123
|
+
# record exists in the database with the given value for the specified
|
124
|
+
# attribute (that maps to a column). When the record is updated,
|
95
125
|
# the same check is made but disregarding the record itself.
|
96
126
|
#
|
97
127
|
# Configuration options:
|
98
|
-
#
|
99
|
-
# * <tt>:
|
100
|
-
#
|
101
|
-
# * <tt>:
|
102
|
-
#
|
103
|
-
# * <tt>:
|
104
|
-
#
|
105
|
-
#
|
106
|
-
# * <tt>:
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
128
|
+
#
|
129
|
+
# * <tt>:message</tt> - Specifies a custom error message (default is:
|
130
|
+
# "has already been taken").
|
131
|
+
# * <tt>:scope</tt> - One or more columns by which to limit the scope of
|
132
|
+
# the uniqueness constraint.
|
133
|
+
# * <tt>:conditions</tt> - Specify the conditions to be included as a
|
134
|
+
# <tt>WHERE</tt> SQL fragment to limit the uniqueness constraint lookup
|
135
|
+
# (e.g. <tt>conditions: where('status = ?', 'active')</tt>).
|
136
|
+
# * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by
|
137
|
+
# non-text columns (+true+ by default).
|
138
|
+
# * <tt>:allow_nil</tt> - If set to +true+, skips this validation if the
|
139
|
+
# attribute is +nil+ (default is +false+).
|
140
|
+
# * <tt>:allow_blank</tt> - If set to +true+, skips this validation if the
|
141
|
+
# attribute is blank (default is +false+).
|
142
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
143
|
+
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
|
144
|
+
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
|
145
|
+
# proc or string should return or evaluate to a +true+ or +false+ value.
|
146
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to
|
147
|
+
# determine if the validation should ot occur (e.g. <tt>unless: :skip_validation</tt>,
|
148
|
+
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
149
|
+
# method, proc or string should return or evaluate to a +true+ or +false+
|
150
|
+
# value.
|
110
151
|
#
|
111
152
|
# === Concurrency and integrity
|
112
153
|
#
|
@@ -158,20 +199,20 @@ module ActiveRecord
|
|
158
199
|
# can catch it and restart the transaction (e.g. by telling the user
|
159
200
|
# that the title already exists, and asking him to re-enter the title).
|
160
201
|
# This technique is also known as optimistic concurrency control:
|
161
|
-
# http://en.wikipedia.org/wiki/Optimistic_concurrency_control
|
202
|
+
# http://en.wikipedia.org/wiki/Optimistic_concurrency_control.
|
162
203
|
#
|
163
204
|
# The bundled ActiveRecord::ConnectionAdapters distinguish unique index
|
164
205
|
# constraint errors from other types of database errors by throwing an
|
165
|
-
# ActiveRecord::RecordNotUnique exception.
|
166
|
-
#
|
167
|
-
#
|
206
|
+
# ActiveRecord::RecordNotUnique exception. For other adapters you will
|
207
|
+
# have to parse the (database-specific) exception message to detect such
|
208
|
+
# a case.
|
209
|
+
#
|
168
210
|
# The following bundled adapters throw the ActiveRecord::RecordNotUnique exception:
|
169
|
-
# * ActiveRecord::ConnectionAdapters::MysqlAdapter
|
170
|
-
# * ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
171
|
-
# * ActiveRecord::ConnectionAdapters::SQLiteAdapter
|
172
|
-
# * ActiveRecord::ConnectionAdapters::SQLite3Adapter
|
173
|
-
# * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
174
211
|
#
|
212
|
+
# * ActiveRecord::ConnectionAdapters::MysqlAdapter.
|
213
|
+
# * ActiveRecord::ConnectionAdapters::Mysql2Adapter.
|
214
|
+
# * ActiveRecord::ConnectionAdapters::SQLite3Adapter.
|
215
|
+
# * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.
|
175
216
|
def validates_uniqueness_of(*attr_names)
|
176
217
|
validates_with UniquenessValidator, _merge_attributes(attr_names)
|
177
218
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
require 'rails/generators/named_base'
|
2
2
|
require 'rails/generators/migration'
|
3
3
|
require 'rails/generators/active_model'
|
4
|
-
require 'rails/generators/active_record/migration'
|
5
4
|
require 'active_record'
|
6
5
|
|
7
6
|
module ActiveRecord
|
8
|
-
module Generators
|
9
|
-
class Base < Rails::Generators::NamedBase
|
7
|
+
module Generators # :nodoc:
|
8
|
+
class Base < Rails::Generators::NamedBase # :nodoc:
|
10
9
|
include Rails::Generators::Migration
|
11
|
-
extend ActiveRecord::Generators::Migration
|
12
10
|
|
13
11
|
# Set the current directory as base for the inherited generators.
|
14
12
|
def self.base_root
|
@@ -16,7 +14,7 @@ module ActiveRecord
|
|
16
14
|
end
|
17
15
|
|
18
16
|
# Implement the required interface for Rails::Generators::Migration.
|
19
|
-
def self.next_migration_number(dirname)
|
17
|
+
def self.next_migration_number(dirname)
|
20
18
|
next_migration_number = current_migration_number(dirname) + 1
|
21
19
|
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
22
20
|
end
|
@@ -1,25 +1,55 @@
|
|
1
1
|
require 'rails/generators/active_record'
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
-
module Generators
|
5
|
-
class MigrationGenerator < Base
|
4
|
+
module Generators # :nodoc:
|
5
|
+
class MigrationGenerator < Base # :nodoc:
|
6
6
|
argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
|
7
7
|
|
8
8
|
def create_migration_file
|
9
9
|
set_local_assigns!
|
10
|
+
validate_file_name!
|
10
11
|
migration_template "migration.rb", "db/migrate/#{file_name}.rb"
|
11
12
|
end
|
12
13
|
|
13
14
|
protected
|
14
|
-
|
15
|
+
attr_reader :migration_action, :join_tables
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def set_local_assigns!
|
18
|
+
case file_name
|
19
|
+
when /^(add|remove)_.*_(?:to|from)_(.*)/
|
20
|
+
@migration_action = $1
|
21
|
+
@table_name = $2.pluralize
|
22
|
+
when /join_table/
|
23
|
+
if attributes.length == 2
|
24
|
+
@migration_action = 'join'
|
25
|
+
@join_tables = attributes.map(&:plural_name)
|
26
|
+
|
27
|
+
set_index_names
|
20
28
|
end
|
21
29
|
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_index_names
|
33
|
+
attributes.each_with_index do |attr, i|
|
34
|
+
attr.index_name = [attr, attributes[i - 1]].map{ |a| index_name_for(a) }
|
35
|
+
end
|
36
|
+
end
|
22
37
|
|
38
|
+
def index_name_for(attribute)
|
39
|
+
if attribute.foreign_key?
|
40
|
+
attribute.name
|
41
|
+
else
|
42
|
+
attribute.name.singularize.foreign_key
|
43
|
+
end.to_sym
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def validate_file_name!
|
49
|
+
unless file_name =~ /^[_a-z0-9]+$/
|
50
|
+
raise IllegalMigrationNameError.new(file_name)
|
51
|
+
end
|
52
|
+
end
|
23
53
|
end
|
24
54
|
end
|
25
55
|
end
|
@@ -2,32 +2,37 @@ class <%= migration_class_name %> < ActiveRecord::Migration
|
|
2
2
|
<%- if migration_action == 'add' -%>
|
3
3
|
def change
|
4
4
|
<% attributes.each do |attribute| -%>
|
5
|
+
<%- if attribute.reference? -%>
|
6
|
+
add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
|
7
|
+
<%- else -%>
|
5
8
|
add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
|
6
9
|
<%- if attribute.has_index? -%>
|
7
10
|
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
8
11
|
<%- end -%>
|
12
|
+
<%- end -%>
|
9
13
|
<%- end -%>
|
10
14
|
end
|
15
|
+
<%- elsif migration_action == 'join' -%>
|
16
|
+
def change
|
17
|
+
create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
|
18
|
+
<%- attributes.each do |attribute| -%>
|
19
|
+
<%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
|
20
|
+
<%- end -%>
|
21
|
+
end
|
22
|
+
end
|
11
23
|
<%- else -%>
|
12
|
-
def
|
24
|
+
def change
|
13
25
|
<% attributes.each do |attribute| -%>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
26
|
+
<%- if migration_action -%>
|
27
|
+
<%- if attribute.reference? -%>
|
28
|
+
remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
|
29
|
+
<%- else -%>
|
30
|
+
<%- if attribute.has_index? -%>
|
31
|
+
remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
18
32
|
<%- end -%>
|
33
|
+
remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
|
19
34
|
<%- end -%>
|
20
35
|
<%- end -%>
|
21
|
-
end
|
22
|
-
|
23
|
-
def down
|
24
|
-
<% attributes.reverse.each do |attribute| -%>
|
25
|
-
<%- if migration_action -%>
|
26
|
-
<%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
|
27
|
-
<%- if attribute.has_index? && migration_action == 'remove' -%>
|
28
|
-
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
29
|
-
<%- end -%>
|
30
|
-
<%- end -%>
|
31
36
|
<%- end -%>
|
32
37
|
end
|
33
38
|
<%- end -%>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'rails/generators/active_record'
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
-
module Generators
|
5
|
-
class ModelGenerator < Base
|
4
|
+
module Generators # :nodoc:
|
5
|
+
class ModelGenerator < Base # :nodoc:
|
6
6
|
argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
|
7
7
|
|
8
8
|
check_class_collision
|
@@ -14,6 +14,7 @@ module ActiveRecord
|
|
14
14
|
|
15
15
|
def create_migration_file
|
16
16
|
return unless options[:migration] && options[:parent].nil?
|
17
|
+
attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
|
17
18
|
migration_template "migration.rb", "db/migrate/create_#{table_name}.rb"
|
18
19
|
end
|
19
20
|
|
@@ -27,7 +28,7 @@ module ActiveRecord
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def attributes_with_index
|
30
|
-
attributes.select { |a| a.
|
31
|
+
attributes.select { |a| !a.reference? && a.has_index? }
|
31
32
|
end
|
32
33
|
|
33
34
|
def accessible_attributes
|
@@ -1,12 +1,7 @@
|
|
1
1
|
<% module_namespacing do -%>
|
2
2
|
class <%= class_name %> < <%= parent_class_name.classify %>
|
3
3
|
<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
|
4
|
-
belongs_to :<%= attribute.name %>
|
5
|
-
<% end -%>
|
6
|
-
<% if !accessible_attributes.empty? -%>
|
7
|
-
attr_accessible <%= accessible_attributes.map {|a| ":#{a.name}" }.sort.join(', ') %>
|
8
|
-
<% else -%>
|
9
|
-
# attr_accessible :title, :body
|
4
|
+
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
10
5
|
<% end -%>
|
11
6
|
end
|
12
7
|
<% end -%>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2013-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.0.0.beta1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 4.0.0.beta1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.0.0.beta1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.0.0.beta1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: arel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 4.0.0.beta1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 4.0.0.beta1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: activerecord-deprecated_finders
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.3
|
61
|
+
version: 0.0.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.3
|
68
|
+
version: 0.0.3
|
69
69
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
70
70
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
71
71
|
migrations, and testing come baked-in.
|
@@ -81,9 +81,7 @@ files:
|
|
81
81
|
- examples/associations.png
|
82
82
|
- examples/performance.rb
|
83
83
|
- examples/simple.rb
|
84
|
-
- lib/active_record.rb
|
85
84
|
- lib/active_record/aggregations.rb
|
86
|
-
- lib/active_record/associations.rb
|
87
85
|
- lib/active_record/associations/alias_tracker.rb
|
88
86
|
- lib/active_record/associations/association.rb
|
89
87
|
- lib/active_record/associations/association_scope.rb
|
@@ -103,12 +101,11 @@ files:
|
|
103
101
|
- lib/active_record/associations/has_many_through_association.rb
|
104
102
|
- lib/active_record/associations/has_one_association.rb
|
105
103
|
- lib/active_record/associations/has_one_through_association.rb
|
106
|
-
- lib/active_record/associations/join_dependency.rb
|
107
104
|
- lib/active_record/associations/join_dependency/join_association.rb
|
108
105
|
- lib/active_record/associations/join_dependency/join_base.rb
|
109
106
|
- lib/active_record/associations/join_dependency/join_part.rb
|
107
|
+
- lib/active_record/associations/join_dependency.rb
|
110
108
|
- lib/active_record/associations/join_helper.rb
|
111
|
-
- lib/active_record/associations/preloader.rb
|
112
109
|
- lib/active_record/associations/preloader/association.rb
|
113
110
|
- lib/active_record/associations/preloader/belongs_to.rb
|
114
111
|
- lib/active_record/associations/preloader/collection_association.rb
|
@@ -119,12 +116,12 @@ files:
|
|
119
116
|
- lib/active_record/associations/preloader/has_one_through.rb
|
120
117
|
- lib/active_record/associations/preloader/singular_association.rb
|
121
118
|
- lib/active_record/associations/preloader/through_association.rb
|
119
|
+
- lib/active_record/associations/preloader.rb
|
122
120
|
- lib/active_record/associations/singular_association.rb
|
123
121
|
- lib/active_record/associations/through_association.rb
|
122
|
+
- lib/active_record/associations.rb
|
124
123
|
- lib/active_record/attribute_assignment.rb
|
125
|
-
- lib/active_record/attribute_methods.rb
|
126
124
|
- lib/active_record/attribute_methods/before_type_cast.rb
|
127
|
-
- lib/active_record/attribute_methods/deprecated_underscore_read.rb
|
128
125
|
- lib/active_record/attribute_methods/dirty.rb
|
129
126
|
- lib/active_record/attribute_methods/primary_key.rb
|
130
127
|
- lib/active_record/attribute_methods/query.rb
|
@@ -132,49 +129,58 @@ files:
|
|
132
129
|
- lib/active_record/attribute_methods/serialization.rb
|
133
130
|
- lib/active_record/attribute_methods/time_zone_conversion.rb
|
134
131
|
- lib/active_record/attribute_methods/write.rb
|
132
|
+
- lib/active_record/attribute_methods.rb
|
135
133
|
- lib/active_record/autosave_association.rb
|
136
134
|
- lib/active_record/base.rb
|
137
135
|
- lib/active_record/callbacks.rb
|
138
136
|
- lib/active_record/coders/yaml_column.rb
|
139
137
|
- lib/active_record/connection_adapters/abstract/connection_pool.rb
|
140
|
-
- lib/active_record/connection_adapters/abstract/connection_specification.rb
|
141
138
|
- lib/active_record/connection_adapters/abstract/database_limits.rb
|
142
139
|
- lib/active_record/connection_adapters/abstract/database_statements.rb
|
143
140
|
- lib/active_record/connection_adapters/abstract/query_cache.rb
|
144
141
|
- lib/active_record/connection_adapters/abstract/quoting.rb
|
145
142
|
- lib/active_record/connection_adapters/abstract/schema_definitions.rb
|
143
|
+
- lib/active_record/connection_adapters/abstract/schema_dumper.rb
|
146
144
|
- lib/active_record/connection_adapters/abstract/schema_statements.rb
|
145
|
+
- lib/active_record/connection_adapters/abstract/transaction.rb
|
147
146
|
- lib/active_record/connection_adapters/abstract_adapter.rb
|
148
147
|
- lib/active_record/connection_adapters/abstract_mysql_adapter.rb
|
149
148
|
- lib/active_record/connection_adapters/column.rb
|
149
|
+
- lib/active_record/connection_adapters/connection_specification.rb
|
150
150
|
- lib/active_record/connection_adapters/mysql2_adapter.rb
|
151
151
|
- lib/active_record/connection_adapters/mysql_adapter.rb
|
152
|
+
- lib/active_record/connection_adapters/postgresql/array_parser.rb
|
153
|
+
- lib/active_record/connection_adapters/postgresql/cast.rb
|
154
|
+
- lib/active_record/connection_adapters/postgresql/database_statements.rb
|
155
|
+
- lib/active_record/connection_adapters/postgresql/oid.rb
|
156
|
+
- lib/active_record/connection_adapters/postgresql/quoting.rb
|
157
|
+
- lib/active_record/connection_adapters/postgresql/referential_integrity.rb
|
158
|
+
- lib/active_record/connection_adapters/postgresql/schema_statements.rb
|
152
159
|
- lib/active_record/connection_adapters/postgresql_adapter.rb
|
153
160
|
- lib/active_record/connection_adapters/schema_cache.rb
|
154
161
|
- lib/active_record/connection_adapters/sqlite3_adapter.rb
|
155
|
-
- lib/active_record/connection_adapters/sqlite_adapter.rb
|
156
162
|
- lib/active_record/connection_adapters/statement_pool.rb
|
163
|
+
- lib/active_record/connection_handling.rb
|
164
|
+
- lib/active_record/core.rb
|
157
165
|
- lib/active_record/counter_cache.rb
|
158
|
-
- lib/active_record/dynamic_finder_match.rb
|
159
166
|
- lib/active_record/dynamic_matchers.rb
|
160
|
-
- lib/active_record/dynamic_scope_match.rb
|
161
167
|
- lib/active_record/errors.rb
|
162
168
|
- lib/active_record/explain.rb
|
163
169
|
- lib/active_record/explain_subscriber.rb
|
170
|
+
- lib/active_record/fixture_set/file.rb
|
164
171
|
- lib/active_record/fixtures.rb
|
165
|
-
- lib/active_record/fixtures/file.rb
|
166
|
-
- lib/active_record/identity_map.rb
|
167
172
|
- lib/active_record/inheritance.rb
|
168
173
|
- lib/active_record/integration.rb
|
169
174
|
- lib/active_record/locale/en.yml
|
170
175
|
- lib/active_record/locking/optimistic.rb
|
171
176
|
- lib/active_record/locking/pessimistic.rb
|
172
177
|
- lib/active_record/log_subscriber.rb
|
173
|
-
- lib/active_record/migration.rb
|
174
178
|
- lib/active_record/migration/command_recorder.rb
|
179
|
+
- lib/active_record/migration/join_table.rb
|
180
|
+
- lib/active_record/migration.rb
|
175
181
|
- lib/active_record/model_schema.rb
|
176
182
|
- lib/active_record/nested_attributes.rb
|
177
|
-
- lib/active_record/
|
183
|
+
- lib/active_record/null_relation.rb
|
178
184
|
- lib/active_record/persistence.rb
|
179
185
|
- lib/active_record/query_cache.rb
|
180
186
|
- lib/active_record/querying.rb
|
@@ -185,70 +191,71 @@ files:
|
|
185
191
|
- lib/active_record/railties/jdbcmysql_error.rb
|
186
192
|
- lib/active_record/readonly_attributes.rb
|
187
193
|
- lib/active_record/reflection.rb
|
188
|
-
- lib/active_record/relation.rb
|
189
194
|
- lib/active_record/relation/batches.rb
|
190
195
|
- lib/active_record/relation/calculations.rb
|
191
196
|
- lib/active_record/relation/delegation.rb
|
192
197
|
- lib/active_record/relation/finder_methods.rb
|
198
|
+
- lib/active_record/relation/merger.rb
|
193
199
|
- lib/active_record/relation/predicate_builder.rb
|
194
200
|
- lib/active_record/relation/query_methods.rb
|
195
201
|
- lib/active_record/relation/spawn_methods.rb
|
202
|
+
- lib/active_record/relation.rb
|
196
203
|
- lib/active_record/result.rb
|
197
204
|
- lib/active_record/sanitization.rb
|
198
205
|
- lib/active_record/schema.rb
|
199
206
|
- lib/active_record/schema_dumper.rb
|
200
|
-
- lib/active_record/
|
207
|
+
- lib/active_record/schema_migration.rb
|
201
208
|
- lib/active_record/scoping/default.rb
|
202
209
|
- lib/active_record/scoping/named.rb
|
210
|
+
- lib/active_record/scoping.rb
|
203
211
|
- lib/active_record/serialization.rb
|
204
212
|
- lib/active_record/serializers/xml_serializer.rb
|
205
|
-
- lib/active_record/session_store.rb
|
206
213
|
- lib/active_record/store.rb
|
214
|
+
- lib/active_record/tasks/database_tasks.rb
|
215
|
+
- lib/active_record/tasks/mysql_database_tasks.rb
|
216
|
+
- lib/active_record/tasks/postgresql_database_tasks.rb
|
217
|
+
- lib/active_record/tasks/sqlite_database_tasks.rb
|
207
218
|
- lib/active_record/test_case.rb
|
208
219
|
- lib/active_record/timestamp.rb
|
209
220
|
- lib/active_record/transactions.rb
|
210
221
|
- lib/active_record/translation.rb
|
211
|
-
- lib/active_record/validations.rb
|
212
222
|
- lib/active_record/validations/associated.rb
|
223
|
+
- lib/active_record/validations/presence.rb
|
213
224
|
- lib/active_record/validations/uniqueness.rb
|
225
|
+
- lib/active_record/validations.rb
|
214
226
|
- lib/active_record/version.rb
|
215
|
-
- lib/
|
216
|
-
- lib/rails/generators/active_record/migration.rb
|
227
|
+
- lib/active_record.rb
|
217
228
|
- lib/rails/generators/active_record/migration/migration_generator.rb
|
218
229
|
- lib/rails/generators/active_record/migration/templates/migration.rb
|
219
230
|
- lib/rails/generators/active_record/model/model_generator.rb
|
220
231
|
- lib/rails/generators/active_record/model/templates/migration.rb
|
221
232
|
- lib/rails/generators/active_record/model/templates/model.rb
|
222
233
|
- lib/rails/generators/active_record/model/templates/module.rb
|
223
|
-
- lib/rails/generators/active_record
|
224
|
-
- lib/rails/generators/active_record/observer/templates/observer.rb
|
225
|
-
- lib/rails/generators/active_record/session_migration/session_migration_generator.rb
|
226
|
-
- lib/rails/generators/active_record/session_migration/templates/migration.rb
|
234
|
+
- lib/rails/generators/active_record.rb
|
227
235
|
homepage: http://www.rubyonrails.org
|
228
236
|
licenses:
|
229
237
|
- MIT
|
230
238
|
metadata: {}
|
231
239
|
post_install_message:
|
232
240
|
rdoc_options:
|
233
|
-
-
|
241
|
+
- --main
|
234
242
|
- README.rdoc
|
235
243
|
require_paths:
|
236
244
|
- lib
|
237
245
|
required_ruby_version: !ruby/object:Gem::Requirement
|
238
246
|
requirements:
|
239
|
-
- -
|
247
|
+
- - '>='
|
240
248
|
- !ruby/object:Gem::Version
|
241
|
-
version: 1.
|
249
|
+
version: 1.9.3
|
242
250
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
251
|
requirements:
|
244
|
-
- -
|
252
|
+
- - '>'
|
245
253
|
- !ruby/object:Gem::Version
|
246
|
-
version:
|
254
|
+
version: 1.3.1
|
247
255
|
requirements: []
|
248
256
|
rubyforge_project:
|
249
|
-
rubygems_version: 2.
|
257
|
+
rubygems_version: 2.0.0
|
250
258
|
signing_key:
|
251
259
|
specification_version: 4
|
252
260
|
summary: Object-relational mapper framework (part of Rails).
|
253
261
|
test_files: []
|
254
|
-
has_rdoc:
|