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.

Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1024 -543
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +20 -29
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +55 -44
  7. data/lib/active_record/aggregations.rb +40 -34
  8. data/lib/active_record/associations.rb +204 -276
  9. data/lib/active_record/associations/alias_tracker.rb +1 -1
  10. data/lib/active_record/associations/association.rb +30 -35
  11. data/lib/active_record/associations/association_scope.rb +40 -40
  12. data/lib/active_record/associations/belongs_to_association.rb +15 -2
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +35 -57
  15. data/lib/active_record/associations/builder/collection_association.rb +54 -40
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -64
  18. data/lib/active_record/associations/builder/has_one.rb +13 -50
  19. data/lib/active_record/associations/builder/singular_association.rb +13 -13
  20. data/lib/active_record/associations/collection_association.rb +92 -88
  21. data/lib/active_record/associations/collection_proxy.rb +913 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -10
  23. data/lib/active_record/associations/has_many_association.rb +35 -9
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -14
  25. data/lib/active_record/associations/has_one_association.rb +33 -13
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +2 -2
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  30. data/lib/active_record/associations/join_helper.rb +1 -11
  31. data/lib/active_record/associations/preloader.rb +14 -17
  32. data/lib/active_record/associations/preloader/association.rb +29 -33
  33. data/lib/active_record/associations/preloader/collection_association.rb +1 -1
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
  35. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  36. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +13 -17
  38. data/lib/active_record/associations/singular_association.rb +11 -11
  39. data/lib/active_record/associations/through_association.rb +2 -2
  40. data/lib/active_record/attribute_assignment.rb +133 -153
  41. data/lib/active_record/attribute_methods.rb +196 -93
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  43. data/lib/active_record/attribute_methods/dirty.rb +31 -28
  44. data/lib/active_record/attribute_methods/primary_key.rb +38 -30
  45. data/lib/active_record/attribute_methods/query.rb +5 -4
  46. data/lib/active_record/attribute_methods/read.rb +62 -91
  47. data/lib/active_record/attribute_methods/serialization.rb +97 -66
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -45
  49. data/lib/active_record/attribute_methods/write.rb +32 -39
  50. data/lib/active_record/autosave_association.rb +56 -70
  51. data/lib/active_record/base.rb +53 -450
  52. data/lib/active_record/callbacks.rb +53 -18
  53. data/lib/active_record/coders/yaml_column.rb +11 -9
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +353 -197
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -131
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -19
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -3
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +101 -91
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +59 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +225 -96
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +99 -46
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +114 -36
  65. data/lib/active_record/connection_adapters/column.rb +46 -24
  66. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  67. data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -32
  68. data/lib/active_record/connection_adapters/mysql_adapter.rb +181 -64
  69. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  70. data/lib/active_record/connection_adapters/postgresql/cast.rb +132 -0
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid.rb +347 -0
  73. data/lib/active_record/connection_adapters/postgresql/quoting.rb +158 -0
  74. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  75. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +448 -0
  76. data/lib/active_record/connection_adapters/postgresql_adapter.rb +454 -885
  77. data/lib/active_record/connection_adapters/schema_cache.rb +48 -16
  78. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +574 -13
  79. data/lib/active_record/connection_handling.rb +98 -0
  80. data/lib/active_record/core.rb +428 -0
  81. data/lib/active_record/counter_cache.rb +106 -108
  82. data/lib/active_record/dynamic_matchers.rb +110 -63
  83. data/lib/active_record/errors.rb +25 -8
  84. data/lib/active_record/explain.rb +8 -58
  85. data/lib/active_record/explain_subscriber.rb +6 -3
  86. data/lib/active_record/fixture_set/file.rb +56 -0
  87. data/lib/active_record/fixtures.rb +146 -148
  88. data/lib/active_record/inheritance.rb +77 -59
  89. data/lib/active_record/integration.rb +5 -5
  90. data/lib/active_record/locale/en.yml +8 -1
  91. data/lib/active_record/locking/optimistic.rb +38 -42
  92. data/lib/active_record/locking/pessimistic.rb +4 -4
  93. data/lib/active_record/log_subscriber.rb +19 -9
  94. data/lib/active_record/migration.rb +318 -153
  95. data/lib/active_record/migration/command_recorder.rb +90 -31
  96. data/lib/active_record/migration/join_table.rb +15 -0
  97. data/lib/active_record/model_schema.rb +69 -92
  98. data/lib/active_record/nested_attributes.rb +113 -148
  99. data/lib/active_record/null_relation.rb +65 -0
  100. data/lib/active_record/persistence.rb +188 -97
  101. data/lib/active_record/query_cache.rb +18 -36
  102. data/lib/active_record/querying.rb +19 -15
  103. data/lib/active_record/railtie.rb +91 -36
  104. data/lib/active_record/railties/console_sandbox.rb +0 -2
  105. data/lib/active_record/railties/controller_runtime.rb +2 -2
  106. data/lib/active_record/railties/databases.rake +90 -309
  107. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  108. data/lib/active_record/readonly_attributes.rb +7 -3
  109. data/lib/active_record/reflection.rb +72 -56
  110. data/lib/active_record/relation.rb +241 -157
  111. data/lib/active_record/relation/batches.rb +25 -22
  112. data/lib/active_record/relation/calculations.rb +143 -121
  113. data/lib/active_record/relation/delegation.rb +96 -18
  114. data/lib/active_record/relation/finder_methods.rb +117 -183
  115. data/lib/active_record/relation/merger.rb +133 -0
  116. data/lib/active_record/relation/predicate_builder.rb +90 -42
  117. data/lib/active_record/relation/query_methods.rb +666 -136
  118. data/lib/active_record/relation/spawn_methods.rb +43 -150
  119. data/lib/active_record/result.rb +33 -6
  120. data/lib/active_record/sanitization.rb +24 -50
  121. data/lib/active_record/schema.rb +19 -12
  122. data/lib/active_record/schema_dumper.rb +31 -39
  123. data/lib/active_record/schema_migration.rb +36 -0
  124. data/lib/active_record/scoping.rb +0 -124
  125. data/lib/active_record/scoping/default.rb +48 -45
  126. data/lib/active_record/scoping/named.rb +74 -103
  127. data/lib/active_record/serialization.rb +6 -2
  128. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  129. data/lib/active_record/store.rb +119 -15
  130. data/lib/active_record/tasks/database_tasks.rb +158 -0
  131. data/lib/active_record/tasks/mysql_database_tasks.rb +138 -0
  132. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  133. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  134. data/lib/active_record/test_case.rb +61 -38
  135. data/lib/active_record/timestamp.rb +8 -9
  136. data/lib/active_record/transactions.rb +65 -51
  137. data/lib/active_record/validations.rb +17 -15
  138. data/lib/active_record/validations/associated.rb +20 -14
  139. data/lib/active_record/validations/presence.rb +65 -0
  140. data/lib/active_record/validations/uniqueness.rb +93 -52
  141. data/lib/active_record/version.rb +4 -4
  142. data/lib/rails/generators/active_record.rb +3 -5
  143. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -7
  144. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  145. data/lib/rails/generators/active_record/model/model_generator.rb +4 -3
  146. data/lib/rails/generators/active_record/model/templates/model.rb +1 -6
  147. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  148. metadata +53 -46
  149. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  150. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  151. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  152. data/lib/active_record/dynamic_finder_match.rb +0 -68
  153. data/lib/active_record/dynamic_scope_match.rb +0 -23
  154. data/lib/active_record/fixtures/file.rb +0 -65
  155. data/lib/active_record/identity_map.rb +0 -162
  156. data/lib/active_record/observer.rb +0 -121
  157. data/lib/active_record/session_store.rb +0 -360
  158. data/lib/rails/generators/active_record/migration.rb +0 -15
  159. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  160. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  161. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  162. 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(options.reverse_merge(:case_sensitive => true))
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.send(:id))) if record.persisted?
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
- Array.wrap(options[:scope]).each do |scope_item|
29
- scope_value = record.read_attribute(scope_item)
30
- relation = relation.and(table[scope_item].eq(scope_value))
31
- end
24
+ if relation.exists?
25
+ error_options = options.except(:case_sensitive, :scope, :conditions)
26
+ error_options[:value] = value
32
27
 
33
- if finder_class.unscoped.where(relation).exists?
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.insert(0, class_hierarchy.first.superclass)
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 = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if value && column.text?
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
- relation = klass.connection.case_insensitive_comparison(table, attribute, column, value)
61
+ klass.connection.case_insensitive_comparison(table, attribute, column, value)
62
62
  else
63
- value = klass.connection.case_sensitive_modifier(value) if value
64
- relation = table[attribute].eq(value)
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 across the system.
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 unique based on a scope parameter:
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, :scope => :account_id
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 teacher can only be on the schedule once
87
- # per semester for a particular class.
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, :scope => [:semester_id, :class_id]
110
+ # validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
91
111
  # end
92
112
  #
93
- # When the record is created, a check is performed to make sure that no record exists in the database
94
- # with the given value for the specified attribute (that maps to a column). When the record is updated,
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
- # * <tt>:message</tt> - Specifies a custom error message (default is: "has already been taken").
99
- # * <tt>:scope</tt> - One or more columns by which to limit the scope of the uniqueness constraint.
100
- # * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by non-text columns (+true+ by default).
101
- # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
102
- # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
103
- # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
104
- # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
105
- # The method, proc or string should return or evaluate to a true or false value.
106
- # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
107
- # not occur (e.g. <tt>:unless => :skip_validation</tt>, or
108
- # <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The method, proc or string should
109
- # return or evaluate to a true or false value.
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
- # For other adapters you will have to parse the (database-specific) exception
167
- # message to detect such a case.
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,9 +1,9 @@
1
1
  module ActiveRecord
2
2
  module VERSION #:nodoc:
3
- MAJOR = 3
4
- MINOR = 2
5
- TINY = 22
6
- PRE = "5"
3
+ MAJOR = 4
4
+ MINOR = 0
5
+ TINY = 0
6
+ PRE = "beta1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  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 #:nodoc:
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) #:nodoc:
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
- attr_reader :migration_action
15
+ attr_reader :migration_action, :join_tables
15
16
 
16
- def set_local_assigns!
17
- if file_name =~ /^(add|remove)_.*_(?:to|from)_(.*)/
18
- @migration_action = $1
19
- @table_name = $2.pluralize
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 up
24
+ def change
13
25
  <% attributes.each do |attribute| -%>
14
- <%- if migration_action -%>
15
- <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
16
- <%- if attribute.has_index? && migration_action == 'add' -%>
17
- add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
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.has_index? || (a.reference? && options[:indexes]) }
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 -%>
@@ -1,7 +1,7 @@
1
1
  <% module_namespacing do -%>
2
2
  module <%= class_path.map(&:camelize).join('::') %>
3
3
  def self.table_name_prefix
4
- '<%= class_path.join('_') %>_'
4
+ '<%= namespaced? ? namespaced_class_path.join('_') : class_path.join('_') %>_'
5
5
  end
6
6
  end
7
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: 3.2.22.5
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: 2016-09-14 00:00:00.000000000 Z
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: 3.2.22.5
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: 3.2.22.5
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: 3.2.22.5
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: 3.2.22.5
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: 3.0.2
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: 3.0.2
54
+ version: 4.0.0.beta1
55
55
  - !ruby/object:Gem::Dependency
56
- name: tzinfo
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.29
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.29
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/observer.rb
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/scoping.rb
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/rails/generators/active_record.rb
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/observer/observer_generator.rb
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
- - "--main"
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.8.7
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: '0'
254
+ version: 1.3.1
247
255
  requirements: []
248
256
  rubyforge_project:
249
- rubygems_version: 2.6.6
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: