activerecord 4.2.0.beta3 → 4.2.0.beta4

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -2
  3. data/lib/active_record/associations.rb +6 -0
  4. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
  5. data/lib/active_record/associations/collection_association.rb +6 -1
  6. data/lib/active_record/associations/collection_proxy.rb +14 -17
  7. data/lib/active_record/associations/has_many_through_association.rb +9 -6
  8. data/lib/active_record/associations/join_dependency.rb +12 -3
  9. data/lib/active_record/associations/join_dependency/join_part.rb +0 -1
  10. data/lib/active_record/associations/singular_association.rb +6 -1
  11. data/lib/active_record/attribute_methods.rb +7 -4
  12. data/lib/active_record/attribute_methods/serialization.rb +8 -7
  13. data/lib/active_record/attribute_set/builder.rb +5 -2
  14. data/lib/active_record/autosave_association.rb +3 -1
  15. data/lib/active_record/callbacks.rb +5 -5
  16. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +8 -6
  17. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -1
  18. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  19. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +11 -18
  20. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1 -1
  22. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +20 -9
  23. data/lib/active_record/connection_adapters/column.rb +20 -0
  24. data/lib/active_record/connection_adapters/connection_specification.rb +8 -3
  25. data/lib/active_record/connection_adapters/mysql2_adapter.rb +0 -5
  26. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -1
  27. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -3
  28. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +7 -4
  29. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
  30. data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
  31. data/lib/active_record/connection_adapters/postgresql_adapter.rb +4 -8
  32. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -4
  33. data/lib/active_record/core.rb +14 -9
  34. data/lib/active_record/errors.rb +1 -1
  35. data/lib/active_record/fixtures.rb +3 -35
  36. data/lib/active_record/gem_version.rb +1 -1
  37. data/lib/active_record/inheritance.rb +2 -2
  38. data/lib/active_record/model_schema.rb +8 -11
  39. data/lib/active_record/querying.rb +12 -2
  40. data/lib/active_record/railties/databases.rake +1 -1
  41. data/lib/active_record/reflection.rb +24 -12
  42. data/lib/active_record/relation.rb +2 -3
  43. data/lib/active_record/relation/finder_methods.rb +19 -10
  44. data/lib/active_record/relation/merger.rb +15 -15
  45. data/lib/active_record/relation/predicate_builder.rb +1 -1
  46. data/lib/active_record/relation/predicate_builder/array_handler.rb +9 -4
  47. data/lib/active_record/relation/query_methods.rb +6 -3
  48. data/lib/active_record/result.rb +4 -0
  49. data/lib/active_record/schema_dumper.rb +2 -0
  50. data/lib/active_record/scoping/named.rb +4 -0
  51. data/lib/active_record/tasks/database_tasks.rb +6 -3
  52. data/lib/active_record/transactions.rb +3 -3
  53. data/lib/active_record/type/boolean.rb +12 -1
  54. data/lib/active_record/validations/associated.rb +5 -3
  55. data/lib/active_record/validations/presence.rb +5 -3
  56. metadata +16 -16
@@ -8,7 +8,7 @@ module ActiveRecord
8
8
  module ColumnDumper
9
9
  def column_spec(column, types)
10
10
  spec = prepare_column_options(column, types)
11
- (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.to_s}: ")}
11
+ (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k}: ")}
12
12
  spec
13
13
  end
14
14
 
@@ -629,7 +629,7 @@ module ActiveRecord
629
629
  type = options.delete(:type) || :integer
630
630
  add_column(table_name, "#{ref_name}_id", type, options)
631
631
  add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
632
- add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
632
+ add_index(table_name, polymorphic ? %w[type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
633
633
  end
634
634
  alias :add_belongs_to :add_reference
635
635
 
@@ -91,6 +91,13 @@ module ActiveRecord
91
91
  collation && !collation.match(/_ci$/)
92
92
  end
93
93
 
94
+ def ==(other)
95
+ super &&
96
+ collation == other.collation &&
97
+ strict == other.strict &&
98
+ extra == other.extra
99
+ end
100
+
94
101
  private
95
102
 
96
103
  # MySQL misreports NOT NULL column default when none is given.
@@ -109,6 +116,10 @@ module ActiveRecord
109
116
  raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
110
117
  end
111
118
  end
119
+
120
+ def attributes_for_hash
121
+ super + [collation, strict, extra]
122
+ end
112
123
  end
113
124
 
114
125
  ##
@@ -485,7 +496,7 @@ module ActiveRecord
485
496
  end
486
497
  end
487
498
 
488
- def change_column_default(table_name, column_name, default)
499
+ def change_column_default(table_name, column_name, default) #:nodoc:
489
500
  column = column_for(table_name, column_name)
490
501
  change_column table_name, column_name, column.sql_type, :default => default
491
502
  end
@@ -645,12 +656,6 @@ module ActiveRecord
645
656
  def initialize_type_map(m) # :nodoc:
646
657
  super
647
658
 
648
- m.register_type(%r(enum)i) do |sql_type|
649
- limit = sql_type[/^enum\((.+)\)/i, 1]
650
- .split(',').map{|enum| enum.strip.length - 2}.max
651
- Type::String.new(limit: limit)
652
- end
653
-
654
659
  m.register_type %r(tinytext)i, Type::Text.new(limit: 2**8 - 1)
655
660
  m.register_type %r(tinyblob)i, Type::Binary.new(limit: 2**8 - 1)
656
661
  m.register_type %r(text)i, Type::Text.new(limit: 2**16 - 1)
@@ -671,6 +676,12 @@ module ActiveRecord
671
676
  m.alias_type %r(set)i, 'varchar'
672
677
  m.alias_type %r(year)i, 'integer'
673
678
  m.alias_type %r(bit)i, 'binary'
679
+
680
+ m.register_type(%r(enum)i) do |sql_type|
681
+ limit = sql_type[/^enum\((.+)\)/i, 1]
682
+ .split(',').map{|enum| enum.strip.length - 2}.max
683
+ Type::String.new(limit: limit)
684
+ end
674
685
  end
675
686
 
676
687
  # MySQL is too stupid to create a temporary table for use subquery, so we have
@@ -825,9 +836,9 @@ module ActiveRecord
825
836
  # Gather up all of the SET variables...
826
837
  variable_assignments = variables.map do |k, v|
827
838
  if v == ':default' || v == :default
828
- "@@SESSION.#{k.to_s} = DEFAULT" # Sets the value to the global or compile default
839
+ "@@SESSION.#{k} = DEFAULT" # Sets the value to the global or compile default
829
840
  elsif !v.nil?
830
- "@@SESSION.#{k.to_s} = #{quote(v)}"
841
+ "@@SESSION.#{k} = #{quote(v)}"
831
842
  end
832
843
  # or else nil; compact to clear nils out
833
844
  end.compact.join(', ')
@@ -56,6 +56,26 @@ module ActiveRecord
56
56
  clone.instance_variable_set('@cast_type', type)
57
57
  end
58
58
  end
59
+
60
+ def ==(other)
61
+ other.name == name &&
62
+ other.default == default &&
63
+ other.cast_type == cast_type &&
64
+ other.sql_type == sql_type &&
65
+ other.null == null &&
66
+ other.default_function == default_function
67
+ end
68
+ alias :eql? :==
69
+
70
+ def hash
71
+ attributes_for_hash.hash
72
+ end
73
+
74
+ private
75
+
76
+ def attributes_for_hash
77
+ [self.class, name, default, cast_type, sql_type, null, default_function]
78
+ end
59
79
  end
60
80
  end
61
81
  # :startdoc:
@@ -1,4 +1,5 @@
1
1
  require 'uri'
2
+ require 'active_support/core_ext/string/filters'
2
3
 
3
4
  module ActiveRecord
4
5
  module ConnectionAdapters
@@ -33,7 +34,7 @@ module ActiveRecord
33
34
  def initialize(url)
34
35
  raise "Database URL cannot be empty" if url.blank?
35
36
  @uri = uri_parser.parse(url)
36
- @adapter = @uri.scheme.gsub('-', '_')
37
+ @adapter = @uri.scheme.tr('-', '_')
37
38
  @adapter = "postgresql" if @adapter == "postgres"
38
39
 
39
40
  if @uri.opaque
@@ -221,8 +222,12 @@ module ActiveRecord
221
222
  # this ambiguous behaviour and in the future this function
222
223
  # can be removed in favor of resolve_url_connection.
223
224
  if configurations.key?(spec) || spec !~ /:/
224
- ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
225
- "for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
225
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
226
+ Passing a string to ActiveRecord::Base.establish_connection for a
227
+ configuration lookup is deprecated, please pass a symbol
228
+ (#{spec.to_sym.inspect}) instead.
229
+ MSG
230
+
226
231
  resolve_symbol_connection(spec)
227
232
  else
228
233
  resolve_url_connection(spec)
@@ -232,11 +232,6 @@ module ActiveRecord
232
232
 
233
233
  alias exec_without_stmt exec_query
234
234
 
235
- # Returns an ActiveRecord::Result instance.
236
- def select(sql, name = nil, binds = [])
237
- exec_query(sql, name)
238
- end
239
-
240
235
  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
241
236
  super
242
237
  id_value || @connection.last_id
@@ -465,7 +465,7 @@ module ActiveRecord
465
465
 
466
466
  def select(sql, name = nil, binds = [])
467
467
  @connection.query_with_result = true
468
- rows = exec_query(sql, name, binds)
468
+ rows = super
469
469
  @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
470
470
  rows
471
471
  end
@@ -12,15 +12,15 @@ module ActiveRecord
12
12
 
13
13
  # If the subnet mask is equal to /32, don't output it
14
14
  if subnet_mask == (2**32 - 1)
15
- "\"#{value.to_s}\""
15
+ "\"#{value}\""
16
16
  else
17
- "\"#{value.to_s}/#{subnet_mask.to_s(2).count('1')}\""
17
+ "\"#{value}/#{subnet_mask.to_s(2).count('1')}\""
18
18
  end
19
19
  end
20
20
 
21
21
  def type_cast_for_database(value)
22
22
  if IPAddr === value
23
- "#{value.to_s}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
23
+ "#{value}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
24
24
  else
25
25
  value
26
26
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/string/filters'
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -25,10 +27,11 @@ module ActiveRecord
25
27
  if !infinity?(from) && extracted[:exclude_start]
26
28
  if from.respond_to?(:succ)
27
29
  from = from.succ
28
- ActiveSupport::Deprecation.warn \
29
- "Excluding the beginning of a Range is only partialy supported " \
30
- "through `#succ`. This is not reliable and will be removed in " \
31
- "the future."
30
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
31
+ Excluding the beginning of a Range is only partialy supported
32
+ through `#succ`. This is not reliable and will be removed in
33
+ the future.
34
+ MSG
32
35
  else
33
36
  raise ArgumentError, "The Ruby Range object does not support excluding the beginning of a Range. (unsupported value: '#{value}')"
34
37
  end
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  module OID # :nodoc:
5
5
  # This class uses the data from PostgreSQL pg_type table to build
6
6
  # the OID -> Type mapping.
7
- # - OID is and integer representing the type.
7
+ # - OID is an integer representing the type.
8
8
  # - Type is an OID::Type object.
9
9
  # This class has side effects on the +store+ passed during initialization.
10
10
  class TypeMapInitializer # :nodoc:
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  case value
22
22
  when Float
23
23
  if value.infinite? || value.nan?
24
- "'#{value.to_s}'"
24
+ "'#{value}'"
25
25
  else
26
26
  super
27
27
  end
@@ -78,6 +78,7 @@ module ActiveRecord
78
78
 
79
79
  NATIVE_DATABASE_TYPES = {
80
80
  primary_key: "serial primary key",
81
+ bigserial: "bigserial",
81
82
  string: { name: "character varying" },
82
83
  text: { name: "text" },
83
84
  integer: { name: "integer" },
@@ -94,6 +95,7 @@ module ActiveRecord
94
95
  int8range: { name: "int8range" },
95
96
  binary: { name: "bytea" },
96
97
  boolean: { name: "boolean" },
98
+ bigint: { name: "bigint" },
97
99
  xml: { name: "xml" },
98
100
  tsvector: { name: "tsvector" },
99
101
  hstore: { name: "hstore" },
@@ -677,9 +679,9 @@ module ActiveRecord
677
679
  variables.map do |k, v|
678
680
  if v == ':default' || v == :default
679
681
  # Sets the value to the global or compile default
680
- execute("SET SESSION #{k.to_s} TO DEFAULT", 'SCHEMA')
682
+ execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
681
683
  elsif !v.nil?
682
- execute("SET SESSION #{k.to_s} TO #{quote(v)}", 'SCHEMA')
684
+ execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
683
685
  end
684
686
  end
685
687
  end
@@ -697,12 +699,6 @@ module ActiveRecord
697
699
  exec_query("SELECT currval('#{sequence_name}')", 'SQL')
698
700
  end
699
701
 
700
- # Executes a SELECT query and returns the results, performing any data type
701
- # conversions that are required to be performed here instead of in PostgreSQLColumn.
702
- def select(sql, name = nil, binds = [])
703
- exec_query(sql, name, binds)
704
- end
705
-
706
702
  # Returns the list of a table's column names, data types, and default values.
707
703
  #
708
704
  # The underlying query is roughly:
@@ -514,10 +514,6 @@ module ActiveRecord
514
514
  register_class_with_limit m, %r(char)i, SQLite3String
515
515
  end
516
516
 
517
- def select(sql, name = nil, binds = []) #:nodoc:
518
- exec_query(sql, name, binds)
519
- end
520
-
521
517
  def table_structure(table_name)
522
518
  structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", 'SCHEMA').to_hash
523
519
  raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
@@ -1,6 +1,7 @@
1
+ require 'thread'
1
2
  require 'active_support/core_ext/hash/indifferent_access'
2
3
  require 'active_support/core_ext/object/duplicable'
3
- require 'thread'
4
+ require 'active_support/core_ext/string/filters'
4
5
 
5
6
  module ActiveRecord
6
7
  module Core
@@ -88,8 +89,10 @@ module ActiveRecord
88
89
  mattr_accessor :maintain_test_schema, instance_accessor: false
89
90
 
90
91
  def self.disable_implicit_join_references=(value)
91
- ActiveSupport::Deprecation.warn("Implicit join references were removed with Rails 4.1." \
92
- "Make sure to remove this configuration because it does nothing.")
92
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
93
+ Implicit join references were removed with Rails 4.1.
94
+ Make sure to remove this configuration because it does nothing.
95
+ MSG
93
96
  end
94
97
 
95
98
  class_attribute :default_connection_handler, instance_writer: false
@@ -135,8 +138,10 @@ module ActiveRecord
135
138
  id = ids.first
136
139
  if ActiveRecord::Base === id
137
140
  id = id.id
138
- ActiveSupport::Deprecation.warn "You are passing an instance of ActiveRecord::Base to `find`." \
139
- "Please pass the id of the object by calling `.id`"
141
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
142
+ You are passing an instance of ActiveRecord::Base to `find`.
143
+ Please pass the id of the object by calling `.id`
144
+ MSG
140
145
  end
141
146
  key = primary_key
142
147
 
@@ -272,7 +277,7 @@ module ActiveRecord
272
277
  init_attributes(attributes, options) if attributes
273
278
 
274
279
  yield self if block_given?
275
- run_callbacks :initialize unless _initialize_callbacks.empty?
280
+ _run_initialize_callbacks
276
281
  end
277
282
 
278
283
  # Initialize an empty model object from +coder+. +coder+ must contain
@@ -294,8 +299,8 @@ module ActiveRecord
294
299
 
295
300
  self.class.define_attribute_methods
296
301
 
297
- run_callbacks :find
298
- run_callbacks :initialize
302
+ _run_find_callbacks
303
+ _run_initialize_callbacks
299
304
 
300
305
  self
301
306
  end
@@ -331,7 +336,7 @@ module ActiveRecord
331
336
  @attributes = @attributes.dup
332
337
  @attributes.reset(self.class.primary_key)
333
338
 
334
- run_callbacks(:initialize) unless _initialize_callbacks.empty?
339
+ _run_initialize_callbacks
335
340
 
336
341
  @aggregation_cache = {}
337
342
  @association_cache = {}
@@ -167,7 +167,7 @@ module ActiveRecord
167
167
  def initialize(record, attribute)
168
168
  @record = record
169
169
  @attribute = attribute.to_s
170
- super("unknown attribute: #{attribute}")
170
+ super("unknown attribute '#{attribute}' for #{@record.class}.")
171
171
  end
172
172
 
173
173
  end
@@ -525,7 +525,7 @@ module ActiveRecord
525
525
  conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
526
526
  table_rows = fs.table_rows
527
527
 
528
- table_rows.keys.each do |table|
528
+ table_rows.each_key do |table|
529
529
  conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
530
530
  end
531
531
 
@@ -870,34 +870,9 @@ module ActiveRecord
870
870
  end
871
871
 
872
872
  self.fixture_table_names |= fixture_set_names
873
- require_fixture_classes(fixture_set_names, self.config)
874
873
  setup_fixture_accessors(fixture_set_names)
875
874
  end
876
875
 
877
- def try_to_load_dependency(file_name)
878
- require_dependency file_name
879
- rescue LoadError => e
880
- unless fixture_class_names.key?(file_name.pluralize)
881
- if ActiveRecord::Base.logger
882
- ActiveRecord::Base.logger.warn("Unable to load #{file_name}, make sure you added it to ActiveSupport::TestCase.set_fixture_class")
883
- ActiveRecord::Base.logger.warn("underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
884
- end
885
- end
886
- end
887
-
888
- def require_fixture_classes(fixture_set_names = nil, config = ActiveRecord::Base)
889
- if fixture_set_names
890
- fixture_set_names = fixture_set_names.map { |n| n.to_s }
891
- else
892
- fixture_set_names = fixture_table_names
893
- end
894
-
895
- fixture_set_names.each do |file_name|
896
- file_name = file_name.singularize if config.pluralize_table_names
897
- try_to_load_dependency(file_name)
898
- end
899
- end
900
-
901
876
  def setup_fixture_accessors(fixture_set_names = nil)
902
877
  fixture_set_names = Array(fixture_set_names || fixture_table_names)
903
878
  methods = Module.new do
@@ -974,7 +949,7 @@ module ActiveRecord
974
949
  end
975
950
 
976
951
  # Instantiate fixtures for every test if requested.
977
- instantiate_fixtures(config) if use_instantiated_fixtures
952
+ instantiate_fixtures if use_instantiated_fixtures
978
953
  end
979
954
 
980
955
  def teardown_fixtures
@@ -1001,16 +976,9 @@ module ActiveRecord
1001
976
  Hash[fixtures.map { |f| [f.name, f] }]
1002
977
  end
1003
978
 
1004
- # for pre_loaded_fixtures, only require the classes once. huge speed improvement
1005
- @@required_fixture_classes = false
1006
-
1007
- def instantiate_fixtures(config)
979
+ def instantiate_fixtures
1008
980
  if pre_loaded_fixtures
1009
981
  raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
1010
- unless @@required_fixture_classes
1011
- self.class.require_fixture_classes ActiveRecord::FixtureSet.all_loaded_fixtures.keys, config
1012
- @@required_fixture_classes = true
1013
- end
1014
982
  ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
1015
983
  else
1016
984
  raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
@@ -8,7 +8,7 @@ module ActiveRecord
8
8
  MAJOR = 4
9
9
  MINOR = 2
10
10
  TINY = 0
11
- PRE = "beta3"
11
+ PRE = "beta4"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -80,12 +80,12 @@ module ActiveRecord
80
80
  end
81
81
 
82
82
  def symbolized_base_class
83
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.symbolized_base_class is deprecated and will be removed without replacement.")
83
+ ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_base_class` is deprecated and will be removed without replacement.')
84
84
  @symbolized_base_class ||= base_class.to_s.to_sym
85
85
  end
86
86
 
87
87
  def symbolized_sti_name
88
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.symbolized_sti_name is deprecated and will be removed without replacement.")
88
+ ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_sti_name` is deprecated and will be removed without replacement.')
89
89
  @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
90
90
  end
91
91