activerecord 4.2.0 → 4.2.1.rc1
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 +206 -1
- data/lib/active_record/associations.rb +4 -3
- data/lib/active_record/associations/belongs_to_association.rb +9 -5
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +17 -2
- data/lib/active_record/associations/collection_proxy.rb +5 -0
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +22 -14
- data/lib/active_record/associations/has_many_through_association.rb +2 -2
- data/lib/active_record/associations/has_one_association.rb +1 -0
- data/lib/active_record/associations/through_association.rb +11 -0
- data/lib/active_record/attribute.rb +15 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +5 -0
- data/lib/active_record/attribute_methods/dirty.rb +7 -3
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +5 -1
- data/lib/active_record/attribute_set/builder.rb +11 -1
- data/lib/active_record/attributes.rb +7 -0
- data/lib/active_record/autosave_association.rb +23 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +7 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +12 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +25 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +38 -6
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +13 -6
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +23 -1
- data/lib/active_record/connection_adapters/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +6 -7
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +10 -16
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +13 -7
- data/lib/active_record/counter_cache.rb +1 -1
- data/lib/active_record/fixtures.rb +1 -1
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/locking/optimistic.rb +16 -14
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/nested_attributes.rb +1 -1
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +2 -1
- data/lib/active_record/railties/databases.rake +2 -2
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +15 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +19 -18
- data/lib/active_record/schema_dumper.rb +1 -1
- data/lib/active_record/transactions.rb +6 -8
- data/lib/active_record/type/date_time.rb +14 -3
- data/lib/active_record/type/decimal.rb +9 -1
- data/lib/active_record/type/integer.rb +9 -5
- data/lib/active_record/type/numeric.rb +1 -1
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/string.rb +4 -0
- data/lib/active_record/type/value.rb +4 -0
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -3
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -6
- metadata +10 -9
@@ -341,9 +341,6 @@ module ActiveRecord
|
|
341
341
|
def create_savepoint(name = nil)
|
342
342
|
end
|
343
343
|
|
344
|
-
def rollback_to_savepoint(name = nil)
|
345
|
-
end
|
346
|
-
|
347
344
|
def release_savepoint(name = nil)
|
348
345
|
end
|
349
346
|
|
@@ -385,7 +382,7 @@ module ActiveRecord
|
|
385
382
|
end
|
386
383
|
|
387
384
|
def column_name_for_operation(operation, node) # :nodoc:
|
388
|
-
node.
|
385
|
+
visitor.accept(node, collector).value
|
389
386
|
end
|
390
387
|
|
391
388
|
protected
|
@@ -445,11 +442,21 @@ module ActiveRecord
|
|
445
442
|
end
|
446
443
|
|
447
444
|
def extract_limit(sql_type) # :nodoc:
|
448
|
-
|
445
|
+
case sql_type
|
446
|
+
when /^bigint/i
|
447
|
+
8
|
448
|
+
when /\((.*)\)/
|
449
|
+
$1.to_i
|
450
|
+
end
|
449
451
|
end
|
450
452
|
|
451
453
|
def translate_exception_class(e, sql)
|
452
|
-
|
454
|
+
begin
|
455
|
+
message = "#{e.class.name}: #{e.message}: #{sql}"
|
456
|
+
rescue Encoding::CompatibilityError
|
457
|
+
message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
|
458
|
+
end
|
459
|
+
|
453
460
|
@logger.error message if @logger
|
454
461
|
exception = translate_exception(e, message)
|
455
462
|
exception.set_backtrace e.backtrace
|
@@ -324,7 +324,7 @@ module ActiveRecord
|
|
324
324
|
execute "COMMIT"
|
325
325
|
end
|
326
326
|
|
327
|
-
def
|
327
|
+
def exec_rollback_db_transaction #:nodoc:
|
328
328
|
execute "ROLLBACK"
|
329
329
|
end
|
330
330
|
|
@@ -492,6 +492,8 @@ module ActiveRecord
|
|
492
492
|
|
493
493
|
def rename_index(table_name, old_name, new_name)
|
494
494
|
if supports_rename_index?
|
495
|
+
validate_index_length!(table_name, new_name)
|
496
|
+
|
495
497
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME INDEX #{quote_table_name(old_name)} TO #{quote_table_name(new_name)}"
|
496
498
|
else
|
497
499
|
super
|
@@ -582,6 +584,13 @@ module ActiveRecord
|
|
582
584
|
when 0x1000000..0xffffffff; 'longtext'
|
583
585
|
else raise(ActiveRecordError, "No text type has character length #{limit}")
|
584
586
|
end
|
587
|
+
when 'datetime'
|
588
|
+
return super unless precision
|
589
|
+
|
590
|
+
case precision
|
591
|
+
when 0..6; "datetime(#{precision})"
|
592
|
+
else raise(ActiveRecordError, "No datetime type has precision of #{precision}. The allowed range of precision is from 0 to 6.")
|
593
|
+
end
|
585
594
|
else
|
586
595
|
super
|
587
596
|
end
|
@@ -670,6 +679,11 @@ module ActiveRecord
|
|
670
679
|
m.alias_type %r(year)i, 'integer'
|
671
680
|
m.alias_type %r(bit)i, 'binary'
|
672
681
|
|
682
|
+
m.register_type(%r(datetime)i) do |sql_type|
|
683
|
+
precision = extract_precision(sql_type)
|
684
|
+
MysqlDateTime.new(precision: precision)
|
685
|
+
end
|
686
|
+
|
673
687
|
m.register_type(%r(enum)i) do |sql_type|
|
674
688
|
limit = sql_type[/^enum\((.+)\)/i, 1]
|
675
689
|
.split(',').map{|enum| enum.strip.length - 2}.max
|
@@ -859,6 +873,14 @@ module ActiveRecord
|
|
859
873
|
end
|
860
874
|
end
|
861
875
|
|
876
|
+
class MysqlDateTime < Type::DateTime # :nodoc:
|
877
|
+
private
|
878
|
+
|
879
|
+
def has_precision?
|
880
|
+
precision || 0
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
862
884
|
class MysqlString < Type::String # :nodoc:
|
863
885
|
def type_cast_for_database(value)
|
864
886
|
case value
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
attr_reader :name, :cast_type, :null, :sql_type, :default, :default_function
|
17
17
|
|
18
18
|
delegate :type, :precision, :scale, :limit, :klass, :accessor,
|
19
|
-
:number?, :binary?, :changed?,
|
19
|
+
:text?, :number?, :binary?, :changed?,
|
20
20
|
:type_cast_from_user, :type_cast_from_database, :type_cast_for_database,
|
21
21
|
:type_cast_for_schema,
|
22
22
|
to: :cast_type
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
39
39
|
|
40
40
|
MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
|
41
41
|
def initialize_schema_migrations_table
|
42
|
-
if
|
42
|
+
if charset == 'utf8mb4'
|
43
43
|
ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
|
44
44
|
else
|
45
45
|
ActiveRecord::SchemaMigration.create_table
|
@@ -5,6 +5,15 @@ module ActiveRecord
|
|
5
5
|
class DateTime < Type::DateTime # :nodoc:
|
6
6
|
include Infinity
|
7
7
|
|
8
|
+
def type_cast_for_database(value)
|
9
|
+
if has_precision? && value.acts_like?(:time) && value.year <= 0
|
10
|
+
bce_year = format("%04d", -value.year + 1)
|
11
|
+
super.sub(/^-?\d+/, bce_year) + " BC"
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
8
17
|
def cast_value(value)
|
9
18
|
if value.is_a?(::String)
|
10
19
|
case value
|
@@ -76,15 +76,15 @@ module ActiveRecord
|
|
76
76
|
column(name, :point, options)
|
77
77
|
end
|
78
78
|
|
79
|
-
def bit(name, options)
|
79
|
+
def bit(name, options = {})
|
80
80
|
column(name, :bit, options)
|
81
81
|
end
|
82
82
|
|
83
|
-
def bit_varying(name, options)
|
83
|
+
def bit_varying(name, options = {})
|
84
84
|
column(name, :bit_varying, options)
|
85
85
|
end
|
86
86
|
|
87
|
-
def money(name, options)
|
87
|
+
def money(name, options = {})
|
88
88
|
column(name, :money, options)
|
89
89
|
end
|
90
90
|
end
|
@@ -386,15 +386,15 @@ module ActiveRecord
|
|
386
386
|
|
387
387
|
# Returns just a table's primary key
|
388
388
|
def primary_key(table)
|
389
|
-
|
389
|
+
pks = exec_query(<<-end_sql, 'SCHEMA').rows
|
390
390
|
SELECT attr.attname
|
391
391
|
FROM pg_attribute attr
|
392
|
-
INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey
|
392
|
+
INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = any(cons.conkey)
|
393
393
|
WHERE cons.contype = 'p'
|
394
394
|
AND cons.conrelid = '#{quote_table_name(table)}'::regclass
|
395
395
|
end_sql
|
396
|
-
|
397
|
-
|
396
|
+
return nil unless pks.count == 1
|
397
|
+
pks[0][0]
|
398
398
|
end
|
399
399
|
|
400
400
|
# Renames a table.
|
@@ -484,9 +484,8 @@ module ActiveRecord
|
|
484
484
|
end
|
485
485
|
|
486
486
|
def rename_index(table_name, old_name, new_name)
|
487
|
-
|
488
|
-
|
489
|
-
end
|
487
|
+
validate_index_length!(table_name, new_name)
|
488
|
+
|
490
489
|
execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
|
491
490
|
end
|
492
491
|
|
@@ -64,7 +64,7 @@ module ActiveRecord
|
|
64
64
|
# <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
|
65
65
|
# * <tt>:variables</tt> - An optional hash of additional parameters that
|
66
66
|
# will be used in <tt>SET SESSION key = val</tt> calls on the connection.
|
67
|
-
# * <tt>:insert_returning</tt> - An optional boolean to control the use
|
67
|
+
# * <tt>:insert_returning</tt> - An optional boolean to control the use of <tt>RETURNING</tt> for <tt>INSERT</tt> statements
|
68
68
|
# defaults to true.
|
69
69
|
#
|
70
70
|
# Any further options are used as connection parameters to libpq. See
|
@@ -445,8 +445,8 @@ module ActiveRecord
|
|
445
445
|
|
446
446
|
def initialize_type_map(m) # :nodoc:
|
447
447
|
register_class_with_limit m, 'int2', OID::Integer
|
448
|
-
m
|
449
|
-
m
|
448
|
+
register_class_with_limit m, 'int4', OID::Integer
|
449
|
+
register_class_with_limit m, 'int8', OID::Integer
|
450
450
|
m.alias_type 'oid', 'int2'
|
451
451
|
m.register_type 'float4', OID::Float.new
|
452
452
|
m.alias_type 'float8', 'float4'
|
@@ -50,16 +50,6 @@ module ActiveRecord
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
class SQLite3String < Type::String # :nodoc:
|
54
|
-
def type_cast_for_database(value)
|
55
|
-
if value.is_a?(::String) && value.encoding == Encoding::ASCII_8BIT
|
56
|
-
value.encode(Encoding::UTF_8)
|
57
|
-
else
|
58
|
-
super
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
53
|
# The SQLite3 adapter works SQLite 3.6.16 or newer
|
64
54
|
# with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
|
65
55
|
#
|
@@ -239,6 +229,12 @@ module ActiveRecord
|
|
239
229
|
case value
|
240
230
|
when BigDecimal
|
241
231
|
value.to_f
|
232
|
+
when String
|
233
|
+
if value.encoding == Encoding::ASCII_8BIT
|
234
|
+
super(value.encode(Encoding::UTF_8))
|
235
|
+
else
|
236
|
+
super
|
237
|
+
end
|
242
238
|
else
|
243
239
|
super
|
244
240
|
end
|
@@ -361,7 +357,7 @@ module ActiveRecord
|
|
361
357
|
log('commit transaction',nil) { @connection.commit }
|
362
358
|
end
|
363
359
|
|
364
|
-
def
|
360
|
+
def exec_rollback_db_transaction #:nodoc:
|
365
361
|
log('rollback transaction',nil) { @connection.rollback }
|
366
362
|
end
|
367
363
|
|
@@ -428,10 +424,9 @@ module ActiveRecord
|
|
428
424
|
end
|
429
425
|
|
430
426
|
def primary_key(table_name) #:nodoc:
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
column && column['name']
|
427
|
+
pks = table_structure(table_name).select { |f| f['pk'] > 0 }
|
428
|
+
return nil unless pks.count == 1
|
429
|
+
pks[0]['name']
|
435
430
|
end
|
436
431
|
|
437
432
|
def remove_index!(table_name, index_name) #:nodoc:
|
@@ -509,7 +504,6 @@ module ActiveRecord
|
|
509
504
|
def initialize_type_map(m)
|
510
505
|
super
|
511
506
|
m.register_type(/binary/i, SQLite3Binary.new)
|
512
|
-
register_class_with_limit m, %r(char)i, SQLite3String
|
513
507
|
end
|
514
508
|
|
515
509
|
def table_structure(table_name)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionHandling
|
3
|
-
RAILS_ENV = -> { (Rails.env if defined?(Rails)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
3
|
+
RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
4
4
|
DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
|
5
5
|
|
6
6
|
# Establishes the connection to the database. Accepts a hash as input where
|
data/lib/active_record/core.rb
CHANGED
@@ -114,16 +114,16 @@ module ActiveRecord
|
|
114
114
|
super
|
115
115
|
end
|
116
116
|
|
117
|
-
def initialize_find_by_cache
|
117
|
+
def initialize_find_by_cache # :nodoc:
|
118
118
|
self.find_by_statement_cache = {}.extend(Mutex_m)
|
119
119
|
end
|
120
120
|
|
121
|
-
def inherited(child_class)
|
121
|
+
def inherited(child_class) # :nodoc:
|
122
122
|
child_class.initialize_find_by_cache
|
123
123
|
super
|
124
124
|
end
|
125
125
|
|
126
|
-
def find(*ids)
|
126
|
+
def find(*ids) # :nodoc:
|
127
127
|
# We don't have cache keys for this stuff yet
|
128
128
|
return super unless ids.length == 1
|
129
129
|
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
@@ -131,6 +131,7 @@ module ActiveRecord
|
|
131
131
|
return super if block_given? ||
|
132
132
|
primary_key.nil? ||
|
133
133
|
default_scopes.any? ||
|
134
|
+
current_scope ||
|
134
135
|
columns_hash.include?(inheritance_column) ||
|
135
136
|
ids.first.kind_of?(Array)
|
136
137
|
|
@@ -158,7 +159,7 @@ module ActiveRecord
|
|
158
159
|
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
159
160
|
end
|
160
161
|
|
161
|
-
def find_by(*args)
|
162
|
+
def find_by(*args) # :nodoc:
|
162
163
|
return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
|
163
164
|
return super if default_scopes.any?
|
164
165
|
|
@@ -191,11 +192,11 @@ module ActiveRecord
|
|
191
192
|
end
|
192
193
|
end
|
193
194
|
|
194
|
-
def find_by!(*args)
|
195
|
+
def find_by!(*args) # :nodoc:
|
195
196
|
find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
|
196
197
|
end
|
197
198
|
|
198
|
-
def initialize_generated_modules
|
199
|
+
def initialize_generated_modules # :nodoc:
|
199
200
|
generated_association_methods
|
200
201
|
end
|
201
202
|
|
@@ -270,11 +271,11 @@ module ActiveRecord
|
|
270
271
|
# User.new(first_name: 'Jamie')
|
271
272
|
def initialize(attributes = nil, options = {})
|
272
273
|
@attributes = self.class._default_attributes.dup
|
274
|
+
self.class.define_attribute_methods
|
273
275
|
|
274
276
|
init_internals
|
275
277
|
initialize_internals_callback
|
276
278
|
|
277
|
-
self.class.define_attribute_methods
|
278
279
|
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
279
280
|
# Remove it when we drop support to this gem.
|
280
281
|
init_attributes(attributes, options) if attributes
|
@@ -452,6 +453,7 @@ module ActiveRecord
|
|
452
453
|
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record`
|
453
454
|
# when pp is required.
|
454
455
|
def pretty_print(pp)
|
456
|
+
return super if custom_inspect_method_defined?
|
455
457
|
pp.object_address_group(self) do
|
456
458
|
if defined?(@attributes) && @attributes
|
457
459
|
column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
|
@@ -562,5 +564,9 @@ module ActiveRecord
|
|
562
564
|
@attributes = @attributes.dup
|
563
565
|
end
|
564
566
|
end
|
567
|
+
|
568
|
+
def custom_inspect_method_defined?
|
569
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
570
|
+
end
|
565
571
|
end
|
566
572
|
end
|
@@ -167,7 +167,7 @@ module ActiveRecord
|
|
167
167
|
|
168
168
|
def each_counter_cached_associations
|
169
169
|
_reflections.each do |name, reflection|
|
170
|
-
yield association(name) if reflection.belongs_to? && reflection.counter_cache_column
|
170
|
+
yield association(name.to_sym) if reflection.belongs_to? && reflection.counter_cache_column
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
@@ -633,7 +633,7 @@ module ActiveRecord
|
|
633
633
|
|
634
634
|
# interpolate the fixture label
|
635
635
|
row.each do |key, value|
|
636
|
-
row[key] = value.gsub("$LABEL", label) if value.is_a?(String)
|
636
|
+
row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
|
637
637
|
end
|
638
638
|
|
639
639
|
# generate a primary key if necessary
|
@@ -66,6 +66,15 @@ module ActiveRecord
|
|
66
66
|
send(lock_col + '=', previous_lock_value + 1)
|
67
67
|
end
|
68
68
|
|
69
|
+
def _create_record(attribute_names = self.attribute_names, *) # :nodoc:
|
70
|
+
if locking_enabled?
|
71
|
+
# We always want to persist the locking version, even if we don't detect
|
72
|
+
# a change from the default, since the database might have no default
|
73
|
+
attribute_names |= [self.class.locking_column]
|
74
|
+
end
|
75
|
+
super
|
76
|
+
end
|
77
|
+
|
69
78
|
def _update_record(attribute_names = self.attribute_names) #:nodoc:
|
70
79
|
return super unless locking_enabled?
|
71
80
|
return 0 if attribute_names.empty?
|
@@ -80,17 +89,15 @@ module ActiveRecord
|
|
80
89
|
begin
|
81
90
|
relation = self.class.unscoped
|
82
91
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
92
|
+
affected_rows = relation.where(
|
93
|
+
self.class.primary_key => id,
|
94
|
+
lock_col => previous_lock_value,
|
95
|
+
).update_all(
|
96
|
+
Hash[attribute_names.map do |name|
|
97
|
+
[name, _read_attribute(name)]
|
98
|
+
end]
|
90
99
|
)
|
91
100
|
|
92
|
-
affected_rows = self.class.connection.update stmt
|
93
|
-
|
94
101
|
unless affected_rows == 1
|
95
102
|
raise ActiveRecord::StaleObjectError.new(self, "update")
|
96
103
|
end
|
@@ -187,11 +194,6 @@ module ActiveRecord
|
|
187
194
|
super.to_i
|
188
195
|
end
|
189
196
|
|
190
|
-
def changed?(old_value, *)
|
191
|
-
# Ensure we save if the default was `nil`
|
192
|
-
super || old_value == 0
|
193
|
-
end
|
194
|
-
|
195
197
|
def init_with(coder)
|
196
198
|
__setobj__(coder['subtype'])
|
197
199
|
end
|