activerecord 5.0.0.beta2 → 5.0.0.beta3

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -20
  3. data/lib/active_record/association_relation.rb +1 -1
  4. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -0
  5. data/lib/active_record/associations/collection_association.rb +12 -1
  6. data/lib/active_record/associations/collection_proxy.rb +14 -0
  7. data/lib/active_record/associations/join_dependency/join_association.rb +13 -7
  8. data/lib/active_record/associations/preloader/association.rb +1 -1
  9. data/lib/active_record/associations/singular_association.rb +1 -1
  10. data/lib/active_record/attribute_assignment.rb +0 -8
  11. data/lib/active_record/attribute_methods.rb +0 -24
  12. data/lib/active_record/attribute_methods/read.rb +5 -17
  13. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -2
  14. data/lib/active_record/attribute_methods/write.rb +0 -13
  15. data/lib/active_record/base.rb +0 -1
  16. data/lib/active_record/callbacks.rb +1 -1
  17. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -2
  18. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -2
  19. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -2
  20. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  21. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +4 -6
  22. data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -2
  23. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +10 -16
  24. data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
  25. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +2 -2
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -3
  27. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -1
  28. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -3
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -4
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -1
  31. data/lib/active_record/core.rb +5 -0
  32. data/lib/active_record/gem_version.rb +1 -1
  33. data/lib/active_record/inheritance.rb +1 -1
  34. data/lib/active_record/migration/compatibility.rb +1 -1
  35. data/lib/active_record/nested_attributes.rb +14 -6
  36. data/lib/active_record/null_relation.rb +1 -1
  37. data/lib/active_record/querying.rb +3 -3
  38. data/lib/active_record/reflection.rb +53 -36
  39. data/lib/active_record/relation.rb +26 -18
  40. data/lib/active_record/relation/batches.rb +4 -4
  41. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  42. data/lib/active_record/relation/calculations.rb +2 -10
  43. data/lib/active_record/relation/delegation.rb +2 -1
  44. data/lib/active_record/relation/finder_methods.rb +55 -26
  45. data/lib/active_record/relation/predicate_builder.rb +3 -4
  46. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +10 -0
  47. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  48. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  49. data/lib/active_record/relation/query_methods.rb +11 -7
  50. data/lib/active_record/relation/spawn_methods.rb +1 -1
  51. data/lib/active_record/sanitization.rb +1 -1
  52. data/lib/active_record/schema_dumper.rb +6 -4
  53. data/lib/active_record/scoping/named.rb +10 -0
  54. data/lib/active_record/statement_cache.rb +1 -1
  55. data/lib/active_record/table_metadata.rb +5 -1
  56. data/lib/active_record/tasks/database_tasks.rb +4 -0
  57. data/lib/active_record/validations.rb +1 -1
  58. data/lib/active_record/validations/absence.rb +0 -1
  59. data/lib/active_record/validations/length.rb +0 -12
  60. data/lib/active_record/validations/presence.rb +0 -1
  61. data/lib/active_record/validations/uniqueness.rb +7 -9
  62. data/lib/rails/generators/active_record/model/model_generator.rb +9 -0
  63. data/lib/rails/generators/active_record/model/templates/application_record.rb +3 -0
  64. metadata +9 -8
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  class RelationHandler # :nodoc:
4
4
  def call(attribute, value)
5
5
  if value.select_values.empty?
6
- value = value.select(value.klass.arel_table[value.klass.primary_key])
6
+ value = value.select(value.arel_attribute(value.klass.primary_key))
7
7
  end
8
8
 
9
9
  attribute.in(value.arel)
@@ -655,6 +655,10 @@ module ActiveRecord
655
655
  # # SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'author_id = 3'))
656
656
  #
657
657
  def or(other)
658
+ unless other.is_a? Relation
659
+ raise ArgumentError, "You have passed #{other.class.name} object to #or. Pass an ActiveRecord::Relation object instead."
660
+ end
661
+
658
662
  spawn.or!(other)
659
663
  end
660
664
 
@@ -1093,8 +1097,8 @@ module ActiveRecord
1093
1097
 
1094
1098
  def arel_columns(columns)
1095
1099
  columns.map do |field|
1096
- if (Symbol === field || String === field) && columns_hash.key?(field.to_s) && !from_clause.value
1097
- arel_table[field]
1100
+ if (Symbol === field || String === field) && (klass.has_attribute?(field) || klass.attribute_alias?(field)) && !from_clause.value
1101
+ arel_attribute(field)
1098
1102
  elsif Symbol === field
1099
1103
  connection.quote_table_name(field.to_s)
1100
1104
  else
@@ -1105,13 +1109,15 @@ module ActiveRecord
1105
1109
 
1106
1110
  def reverse_sql_order(order_query)
1107
1111
  if order_query.empty?
1108
- return [table[primary_key].desc] if primary_key
1112
+ return [arel_attribute(primary_key).desc] if primary_key
1109
1113
  raise IrreversibleOrderError,
1110
1114
  "Relation has no current order and table has no primary key to be used as default order"
1111
1115
  end
1112
1116
 
1113
1117
  order_query.flat_map do |o|
1114
1118
  case o
1119
+ when Arel::Attribute
1120
+ o.desc
1115
1121
  when Arel::Nodes::Ordering
1116
1122
  o.reverse
1117
1123
  when String
@@ -1170,12 +1176,10 @@ module ActiveRecord
1170
1176
  order_args.map! do |arg|
1171
1177
  case arg
1172
1178
  when Symbol
1173
- arg = klass.attribute_alias(arg) if klass.attribute_alias?(arg)
1174
- table[arg].asc
1179
+ arel_attribute(arg).asc
1175
1180
  when Hash
1176
1181
  arg.map { |field, dir|
1177
- field = klass.attribute_alias(field) if klass.attribute_alias?(field)
1178
- table[field].send(dir.downcase)
1182
+ arel_attribute(field).send(dir.downcase)
1179
1183
  }
1180
1184
  else
1181
1185
  arg
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  # This is mainly intended for sharing common conditions between multiple associations.
30
30
  def merge(other)
31
31
  if other.is_a?(Array)
32
- to_a & other
32
+ records & other
33
33
  elsif other
34
34
  spawn.merge!(other)
35
35
  else
@@ -60,7 +60,7 @@ module ActiveRecord
60
60
  end
61
61
 
62
62
  # Accepts an array, or string of SQL conditions and sanitizes
63
- # them into a valid SQL fragment for a ORDER clause.
63
+ # them into a valid SQL fragment for an ORDER clause.
64
64
  #
65
65
  # sanitize_sql_for_order(["field(id, ?)", [1,3,2]])
66
66
  # # => "field(id, 1,3,2)"
@@ -178,11 +178,11 @@ HEADER
178
178
  tbl.puts
179
179
  end
180
180
 
181
- indexes(table, tbl)
182
-
183
181
  tbl.puts " end"
184
182
  tbl.puts
185
183
 
184
+ indexes(table, tbl)
185
+
186
186
  tbl.rewind
187
187
  stream.print tbl.read
188
188
  rescue => e
@@ -198,7 +198,8 @@ HEADER
198
198
  if (indexes = @connection.indexes(table)).any?
199
199
  add_index_statements = indexes.map do |index|
200
200
  statement_parts = [
201
- "t.index #{index.columns.inspect}",
201
+ "add_index #{remove_prefix_and_suffix(index.table).inspect}",
202
+ index.columns.inspect,
202
203
  "name: #{index.name.inspect}",
203
204
  ]
204
205
  statement_parts << 'unique: true' if index.unique
@@ -212,10 +213,11 @@ HEADER
212
213
  statement_parts << "using: #{index.using.inspect}" if index.using
213
214
  statement_parts << "type: #{index.type.inspect}" if index.type
214
215
 
215
- " #{statement_parts.join(', ')}"
216
+ " #{statement_parts.join(', ')}"
216
217
  end
217
218
 
218
219
  stream.puts add_index_statements.sort.join("\n")
220
+ stream.puts
219
221
  end
220
222
  end
221
223
 
@@ -151,6 +151,7 @@ module ActiveRecord
151
151
  "a class method with the same name."
152
152
  end
153
153
 
154
+ valid_scope_name?(name)
154
155
  extension = Module.new(&block) if block
155
156
 
156
157
  if body.respond_to?(:to_proc)
@@ -169,6 +170,15 @@ module ActiveRecord
169
170
  end
170
171
  end
171
172
  end
173
+
174
+ protected
175
+
176
+ def valid_scope_name?(name)
177
+ if respond_to?(name, true)
178
+ logger.warn "Creating scope :#{name}. " \
179
+ "Overwriting existing method #{self.name}.#{name}."
180
+ end
181
+ end
172
182
  end
173
183
  end
174
184
  end
@@ -106,7 +106,7 @@ module ActiveRecord
106
106
 
107
107
  sql = query_builder.sql_for bind_values, connection
108
108
 
109
- klass.find_by_sql sql, bind_values
109
+ klass.find_by_sql(sql, bind_values, preparable: true)
110
110
  end
111
111
  alias :call :execute
112
112
  end
@@ -22,7 +22,11 @@ module ActiveRecord
22
22
  end
23
23
 
24
24
  def arel_attribute(column_name)
25
- arel_table[column_name]
25
+ if klass
26
+ klass.arel_attribute(column_name, arel_table)
27
+ else
28
+ arel_table[column_name]
29
+ end
26
30
  end
27
31
 
28
32
  def type(column_name)
@@ -116,7 +116,11 @@ module ActiveRecord
116
116
  end
117
117
 
118
118
  def create_all
119
+ old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base)
119
120
  each_local_configuration { |configuration| create configuration }
121
+ if old_pool
122
+ ActiveRecord::Base.connection_handler.establish_connection(ActiveRecord::Base, old_pool.spec)
123
+ end
120
124
  end
121
125
 
122
126
  def create_current(environment = env)
@@ -45,7 +45,7 @@ module ActiveRecord
45
45
  end
46
46
 
47
47
  # Attempts to save the record just like {ActiveRecord::Base#save}[rdoc-ref:Base#save] but
48
- # will raise a ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid.
48
+ # will raise an ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid.
49
49
  def save!(options={})
50
50
  perform_validations(options) ? super : raise_validation_error
51
51
  end
@@ -2,7 +2,6 @@ module ActiveRecord
2
2
  module Validations
3
3
  class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc:
4
4
  def validate_each(record, attribute, association_or_value)
5
- return unless should_validate?(record)
6
5
  if record.class._reflect_on_association(attribute)
7
6
  association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
8
7
  end
@@ -2,23 +2,11 @@ module ActiveRecord
2
2
  module Validations
3
3
  class LengthValidator < ActiveModel::Validations::LengthValidator # :nodoc:
4
4
  def validate_each(record, attribute, association_or_value)
5
- return unless should_validate?(record) || associations_are_dirty?(record)
6
5
  if association_or_value.respond_to?(:loaded?) && association_or_value.loaded?
7
6
  association_or_value = association_or_value.target.reject(&:marked_for_destruction?)
8
7
  end
9
8
  super
10
9
  end
11
-
12
- def associations_are_dirty?(record)
13
- attributes.any? do |attribute|
14
- value = record.read_attribute_for_validation(attribute)
15
- if value.respond_to?(:loaded?) && value.loaded?
16
- value.target.any?(&:marked_for_destruction?)
17
- else
18
- false
19
- end
20
- end
21
- end
22
10
  end
23
11
 
24
12
  module ClassMethods
@@ -2,7 +2,6 @@ module ActiveRecord
2
2
  module Validations
3
3
  class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
4
4
  def validate_each(record, attribute, association_or_value)
5
- return unless should_validate?(record)
6
5
  if record.class._reflect_on_association(attribute)
7
6
  association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
8
7
  end
@@ -11,15 +11,14 @@ module ActiveRecord
11
11
  end
12
12
 
13
13
  def validate_each(record, attribute, value)
14
- return unless should_validate?(record)
15
14
  finder_class = find_finder_class_for(record)
16
15
  table = finder_class.arel_table
17
16
  value = map_enum_attribute(finder_class, attribute, value)
18
17
 
19
18
  relation = build_relation(finder_class, table, attribute, value)
20
- if record.persisted? && finder_class.primary_key.to_s != attribute.to_s
19
+ if record.persisted?
21
20
  if finder_class.primary_key
22
- relation = relation.where.not(finder_class.primary_key => record.id)
21
+ relation = relation.where.not(finder_class.primary_key => record.id_was)
23
22
  else
24
23
  raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
25
24
  end
@@ -57,14 +56,13 @@ module ActiveRecord
57
56
  value = value.attributes[reflection.klass.primary_key] unless value.nil?
58
57
  end
59
58
 
60
- attribute_name = attribute.to_s
61
-
62
59
  # the attribute may be an aliased attribute
63
- if klass.attribute_aliases[attribute_name]
64
- attribute = klass.attribute_aliases[attribute_name]
65
- attribute_name = attribute.to_s
60
+ if klass.attribute_alias?(attribute)
61
+ attribute = klass.attribute_alias(attribute)
66
62
  end
67
63
 
64
+ attribute_name = attribute.to_s
65
+
68
66
  column = klass.columns_hash[attribute_name]
69
67
  cast_type = klass.type_for_attribute(attribute_name)
70
68
  value = cast_type.serialize(value)
@@ -82,7 +80,7 @@ module ActiveRecord
82
80
  if value.nil?
83
81
  klass.unscoped.where(comparison)
84
82
  else
85
- bind = Relation::QueryAttribute.new(attribute.to_s, value, Type::Value.new)
83
+ bind = Relation::QueryAttribute.new(attribute_name, value, Type::Value.new)
86
84
  klass.unscoped.where(comparison, bind)
87
85
  end
88
86
  rescue RangeError
@@ -22,11 +22,13 @@ module ActiveRecord
22
22
 
23
23
  def create_model_file
24
24
  template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
25
+ generate_application_record
25
26
  end
26
27
 
27
28
  def create_module_file
28
29
  return if regular_class_path.empty?
29
30
  template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
31
+ generate_application_record
30
32
  end
31
33
 
32
34
  hook_for :test_framework
@@ -37,6 +39,13 @@ module ActiveRecord
37
39
  attributes.select { |a| !a.reference? && a.has_index? }
38
40
  end
39
41
 
42
+ # FIXME: Change this file to a symlink once RubyGems 2.5.0 is required.
43
+ def generate_application_record
44
+ if self.behavior == :invoke && !File.exist?('app/models/application_record.rb')
45
+ template 'application_record.rb', 'app/models/application_record.rb'
46
+ end
47
+ end
48
+
40
49
  # Used by the migration template to determine the parent name of the model
41
50
  def parent_class_name
42
51
  options[:parent] || determine_default_parent_class
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ 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: 5.0.0.beta2
4
+ version: 5.0.0.beta3
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-02-01 00:00:00.000000000 Z
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.0.beta2
19
+ version: 5.0.0.beta3
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: 5.0.0.beta2
26
+ version: 5.0.0.beta3
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: 5.0.0.beta2
33
+ version: 5.0.0.beta3
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: 5.0.0.beta2
40
+ version: 5.0.0.beta3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: arel
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -242,6 +242,7 @@ files:
242
242
  - lib/active_record/relation/predicate_builder/base_handler.rb
243
243
  - lib/active_record/relation/predicate_builder/basic_object_handler.rb
244
244
  - lib/active_record/relation/predicate_builder/class_handler.rb
245
+ - lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb
245
246
  - lib/active_record/relation/predicate_builder/range_handler.rb
246
247
  - lib/active_record/relation/predicate_builder/relation_handler.rb
247
248
  - lib/active_record/relation/query_attribute.rb
@@ -299,6 +300,7 @@ files:
299
300
  - lib/rails/generators/active_record/migration/templates/create_table_migration.rb
300
301
  - lib/rails/generators/active_record/migration/templates/migration.rb
301
302
  - lib/rails/generators/active_record/model/model_generator.rb
303
+ - lib/rails/generators/active_record/model/templates/application_record.rb
302
304
  - lib/rails/generators/active_record/model/templates/model.rb
303
305
  - lib/rails/generators/active_record/model/templates/module.rb
304
306
  homepage: http://www.rubyonrails.org
@@ -323,9 +325,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
323
325
  version: 1.3.1
324
326
  requirements: []
325
327
  rubyforge_project:
326
- rubygems_version: 2.5.2
328
+ rubygems_version: 2.5.1
327
329
  signing_key:
328
330
  specification_version: 4
329
331
  summary: Object-relational mapper framework (part of Rails).
330
332
  test_files: []
331
- has_rdoc: