sequel 3.45.0 → 3.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +34 -0
- data/README.rdoc +6 -0
- data/Rakefile +46 -33
- data/doc/release_notes/3.46.0.txt +122 -0
- data/doc/schema_modification.rdoc +42 -6
- data/doc/security.rdoc +379 -0
- data/doc/transactions.rdoc +1 -1
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +11 -0
- data/lib/sequel/adapters/mysql2.rb +3 -9
- data/lib/sequel/adapters/postgres.rb +34 -2
- data/lib/sequel/adapters/shared/cubrid.rb +5 -0
- data/lib/sequel/adapters/shared/mssql.rb +27 -3
- data/lib/sequel/adapters/shared/mysql.rb +25 -4
- data/lib/sequel/adapters/shared/sqlite.rb +12 -1
- data/lib/sequel/connection_pool.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +7 -8
- data/lib/sequel/connection_pool/threaded.rb +7 -8
- data/lib/sequel/core.rb +5 -2
- data/lib/sequel/database.rb +1 -1
- data/lib/sequel/database/connecting.rb +7 -7
- data/lib/sequel/database/features.rb +88 -0
- data/lib/sequel/database/misc.rb +14 -64
- data/lib/sequel/database/query.rb +0 -332
- data/lib/sequel/database/schema_generator.rb +36 -3
- data/lib/sequel/database/schema_methods.rb +48 -12
- data/lib/sequel/database/transactions.rb +344 -0
- data/lib/sequel/dataset/actions.rb +24 -9
- data/lib/sequel/dataset/mutation.rb +20 -0
- data/lib/sequel/dataset/query.rb +0 -17
- data/lib/sequel/dataset/sql.rb +7 -0
- data/lib/sequel/exceptions.rb +10 -6
- data/lib/sequel/extensions/_pretty_table.rb +2 -2
- data/lib/sequel/extensions/looser_typecasting.rb +10 -0
- data/lib/sequel/extensions/migration.rb +5 -2
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +16 -14
- data/lib/sequel/model/base.rb +14 -2
- data/lib/sequel/plugins/composition.rb +3 -3
- data/lib/sequel/plugins/dirty.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +3 -0
- data/lib/sequel/plugins/serialization.rb +7 -17
- data/lib/sequel/plugins/string_stripper.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/sql.rb +3 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +21 -0
- data/spec/adapters/postgres_spec.rb +35 -8
- data/spec/core/database_spec.rb +4 -0
- data/spec/core/dataset_spec.rb +48 -2
- data/spec/core/schema_generator_spec.rb +10 -1
- data/spec/core/schema_spec.rb +69 -0
- data/spec/extensions/composition_spec.rb +21 -2
- data/spec/extensions/dirty_spec.rb +17 -10
- data/spec/extensions/eager_each_spec.rb +4 -1
- data/spec/extensions/looser_typecasting_spec.rb +16 -19
- data/spec/extensions/migration_spec.rb +7 -1
- data/spec/extensions/serialization_spec.rb +22 -0
- data/spec/extensions/single_table_inheritance_spec.rb +3 -2
- data/spec/extensions/validation_helpers_spec.rb +6 -0
- data/spec/integration/dataset_test.rb +5 -0
- data/spec/integration/schema_test.rb +16 -0
- data/spec/model/associations_spec.rb +40 -0
- data/spec/model/base_spec.rb +21 -1
- data/spec/model/record_spec.rb +3 -0
- metadata +14 -10
@@ -10,7 +10,7 @@ module Sequel
|
|
10
10
|
# Action methods defined by Sequel that execute code on the database.
|
11
11
|
ACTION_METHODS = (<<-METHS).split.map{|x| x.to_sym}
|
12
12
|
<< [] []= all avg count columns columns! delete each
|
13
|
-
empty? fetch_rows first get import insert insert_multiple interval last
|
13
|
+
empty? fetch_rows first first! get import insert insert_multiple interval last
|
14
14
|
map max min multi_insert paged_each range select_hash select_hash_groups select_map select_order_map
|
15
15
|
set single_record single_value sum to_csv to_hash to_hash_groups truncate update
|
16
16
|
METHS
|
@@ -176,8 +176,13 @@ module Sequel
|
|
176
176
|
# matching records up to that limit. If no argument is passed,
|
177
177
|
# it returns the first matching record. If any other type of
|
178
178
|
# argument(s) is passed, it is given to filter and the
|
179
|
-
# first matching record is returned.
|
180
|
-
# to filter the dataset before returning anything.
|
179
|
+
# first matching record is returned. If a block is given, it is used
|
180
|
+
# to filter the dataset before returning anything.
|
181
|
+
#
|
182
|
+
# If there are no records in the dataset, returns nil (or an empty
|
183
|
+
# array if an integer argument is given).
|
184
|
+
#
|
185
|
+
# Examples:
|
181
186
|
#
|
182
187
|
# DB[:table].first # SELECT * FROM table LIMIT 1
|
183
188
|
# # => {:id=>7}
|
@@ -217,6 +222,12 @@ module Sequel
|
|
217
222
|
end
|
218
223
|
end
|
219
224
|
|
225
|
+
# Calls first. If first returns nil (signaling that no
|
226
|
+
# row matches), raise a Sequel::NoMatchingRow exception.
|
227
|
+
def first!(*args, &block)
|
228
|
+
first(*args, &block) || raise(Sequel::NoMatchingRow)
|
229
|
+
end
|
230
|
+
|
220
231
|
# Return the column value for the first matching record in the dataset.
|
221
232
|
# Raises an error if both an argument and block is given.
|
222
233
|
#
|
@@ -869,21 +880,25 @@ module Sequel
|
|
869
880
|
# Return a plain symbol given a potentially qualified or aliased symbol,
|
870
881
|
# specifying the symbol that is likely to be used as the hash key
|
871
882
|
# for the column when records are returned.
|
872
|
-
def hash_key_symbol(s)
|
883
|
+
def hash_key_symbol(s, recursing=false)
|
873
884
|
case s
|
874
885
|
when Symbol
|
875
886
|
_, c, a = split_symbol(s)
|
876
887
|
(a || c).to_sym
|
877
888
|
when SQL::Identifier, SQL::Wrapper
|
878
|
-
hash_key_symbol(s.value)
|
889
|
+
hash_key_symbol(s.value, true)
|
879
890
|
when SQL::QualifiedIdentifier
|
880
|
-
hash_key_symbol(s.column)
|
891
|
+
hash_key_symbol(s.column, true)
|
881
892
|
when SQL::AliasedExpression
|
882
|
-
hash_key_symbol(s.aliaz)
|
893
|
+
hash_key_symbol(s.aliaz, true)
|
883
894
|
when String
|
884
|
-
|
895
|
+
if recursing
|
896
|
+
s.to_sym
|
897
|
+
else
|
898
|
+
raise(Error, "#{s.inspect} is not supported, should be a Symbol, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression")
|
899
|
+
end
|
885
900
|
else
|
886
|
-
raise(Error, "#{s.inspect} is not supported, should be a Symbol,
|
901
|
+
raise(Error, "#{s.inspect} is not supported, should be a Symbol, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression")
|
887
902
|
end
|
888
903
|
end
|
889
904
|
|
@@ -11,6 +11,9 @@ module Sequel
|
|
11
11
|
# Setup mutation (e.g. filter!) methods. These operate the same as the
|
12
12
|
# non-! methods, but replace the options of the current dataset with the
|
13
13
|
# options of the resulting dataset.
|
14
|
+
#
|
15
|
+
# Do not call this method with untrusted input, as that can result in
|
16
|
+
# arbitrary code execution.
|
14
17
|
def self.def_mutation_method(*meths)
|
15
18
|
options = meths.pop if meths.last.is_a?(Hash)
|
16
19
|
mod = options[:module] if options
|
@@ -36,6 +39,23 @@ module Sequel
|
|
36
39
|
# a single hash argument and returns the object you want #each to return.
|
37
40
|
attr_accessor :row_proc
|
38
41
|
|
42
|
+
# Load an extension into the receiver. In addition to requiring the extension file, this
|
43
|
+
# also modifies the dataset to work with the extension (usually extending it with a
|
44
|
+
# module defined in the extension file). If no related extension file exists or the
|
45
|
+
# extension does not have specific support for Database objects, an Error will be raised.
|
46
|
+
# Returns self.
|
47
|
+
def extension!(*exts)
|
48
|
+
Sequel.extension(*exts)
|
49
|
+
exts.each do |ext|
|
50
|
+
if pr = Sequel.synchronize{EXTENSIONS[ext]}
|
51
|
+
pr.call(self)
|
52
|
+
else
|
53
|
+
raise(Error, "Extension #{ext} does not have specific support handling individual datasets")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
39
59
|
# Avoid self-referential dataset by cloning.
|
40
60
|
def from_self!(*args, &block)
|
41
61
|
@opts.merge!(clone.from_self(*args, &block).opts)
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -161,23 +161,6 @@ module Sequel
|
|
161
161
|
clone.extension!(*exts)
|
162
162
|
end
|
163
163
|
|
164
|
-
# Load an extension into the receiver. In addition to requiring the extension file, this
|
165
|
-
# also modifies the dataset to work with the extension (usually extending it with a
|
166
|
-
# module defined in the extension file). If no related extension file exists or the
|
167
|
-
# extension does not have specific support for Database objects, an Error will be raised.
|
168
|
-
# Returns self.
|
169
|
-
def extension!(*exts)
|
170
|
-
Sequel.extension(*exts)
|
171
|
-
exts.each do |ext|
|
172
|
-
if pr = Sequel.synchronize{EXTENSIONS[ext]}
|
173
|
-
pr.call(self)
|
174
|
-
else
|
175
|
-
raise(Error, "Extension #{ext} does not have specific support handling individual datasets")
|
176
|
-
end
|
177
|
-
end
|
178
|
-
self
|
179
|
-
end
|
180
|
-
|
181
164
|
# Returns a copy of the dataset with the given conditions imposed upon it.
|
182
165
|
# If the query already has a HAVING clause, then the conditions are imposed in the
|
183
166
|
# HAVING clause. If not, then they are imposed in the WHERE clause.
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -326,6 +326,13 @@ module Sequel
|
|
326
326
|
subselect_sql
|
327
327
|
table_ref
|
328
328
|
END
|
329
|
+
|
330
|
+
# For each of the methods in the given array, define a method with
|
331
|
+
# that name that returns a string with the SQL fragment that the
|
332
|
+
# related *_append method would add.
|
333
|
+
#
|
334
|
+
# Do not call this method with untrusted input, as that can result in
|
335
|
+
# arbitrary code execution.
|
329
336
|
def self.def_append_methods(meths)
|
330
337
|
meths.each do |meth|
|
331
338
|
class_eval(<<-END, __FILE__, __LINE__ + 1)
|
data/lib/sequel/exceptions.rb
CHANGED
@@ -7,8 +7,8 @@ module Sequel
|
|
7
7
|
attr_accessor :wrapped_exception
|
8
8
|
end
|
9
9
|
|
10
|
-
#
|
11
|
-
class AdapterNotFound < Error
|
10
|
+
# Error raised when the adapter requested doesn't exist or can't be loaded.
|
11
|
+
class AdapterNotFound < Error; end
|
12
12
|
|
13
13
|
# Generic error raised by the database adapters, indicating a
|
14
14
|
# problem originating from the database server. Usually raised
|
@@ -48,19 +48,23 @@ module Sequel
|
|
48
48
|
class InvalidOperation < Error; end
|
49
49
|
|
50
50
|
# Error raised when attempting an invalid type conversion.
|
51
|
-
class InvalidValue < Error
|
51
|
+
class InvalidValue < Error; end
|
52
|
+
|
53
|
+
# Error raised when the user requests a record via the first! or similar
|
54
|
+
# method, and the dataset does not yield any rows.
|
55
|
+
class NoMatchingRow < Error; end
|
52
56
|
|
53
57
|
# Error raised when the adapter adapter hasn't implemented a method such as +tables+:
|
54
58
|
class NotImplemented < Error; end
|
55
59
|
|
56
60
|
# Error raised when the connection pool cannot acquire a database connection
|
57
61
|
# before the timeout.
|
58
|
-
class PoolTimeout < Error
|
62
|
+
class PoolTimeout < Error; end
|
59
63
|
|
60
|
-
#
|
64
|
+
# Error that you should raise to signal a rollback of the current transaction.
|
61
65
|
# The transaction block will catch this exception, rollback the current transaction,
|
62
66
|
# and won't reraise it (unless a reraise is requested).
|
63
|
-
class Rollback < Error
|
67
|
+
class Rollback < Error; end
|
64
68
|
|
65
69
|
# Error raised when unbinding a dataset that has multiple different values
|
66
70
|
# for a given variable.
|
@@ -39,12 +39,12 @@ module Sequel
|
|
39
39
|
sizes = Hash.new {0}
|
40
40
|
columns.each do |c|
|
41
41
|
s = c.to_s.size
|
42
|
-
sizes[c
|
42
|
+
sizes[c] = s if s > sizes[c]
|
43
43
|
end
|
44
44
|
records.each do |r|
|
45
45
|
columns.each do |c|
|
46
46
|
s = r[c].to_s.size
|
47
|
-
sizes[c
|
47
|
+
sizes[c] = s if s > sizes[c]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
sizes
|
@@ -15,6 +15,16 @@ module Sequel
|
|
15
15
|
def typecast_value_integer(value)
|
16
16
|
value.to_i
|
17
17
|
end
|
18
|
+
|
19
|
+
# Typecast the value to a BigDecimal, without checking if strings
|
20
|
+
# have a valid format.
|
21
|
+
def typecast_value_decimal(value)
|
22
|
+
if value.is_a?(String)
|
23
|
+
BigDecimal.new(value)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
18
28
|
end
|
19
29
|
|
20
30
|
Database.register_extension(:looser_typecasting, LooserTypecasting)
|
@@ -241,11 +241,14 @@ module Sequel
|
|
241
241
|
@actions << [:drop_constraint, args.first]
|
242
242
|
end
|
243
243
|
|
244
|
-
def add_foreign_key(*args)
|
244
|
+
def add_foreign_key(key, table, *args)
|
245
|
+
@actions << [:drop_foreign_key, key, *args]
|
246
|
+
end
|
247
|
+
|
248
|
+
def add_primary_key(*args)
|
245
249
|
raise if args.first.is_a?(Array)
|
246
250
|
@actions << [:drop_column, args.first]
|
247
251
|
end
|
248
|
-
alias add_primary_key add_foreign_key
|
249
252
|
|
250
253
|
def add_index(*args)
|
251
254
|
@actions << [:drop_index, *args]
|
data/lib/sequel/model.rb
CHANGED
@@ -72,7 +72,7 @@ module Sequel
|
|
72
72
|
|
73
73
|
# Class methods added to model that call the method of the same name on the dataset
|
74
74
|
DATASET_METHODS = (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS +
|
75
|
-
[:
|
75
|
+
[:each_page, :each_server, :print]) - [:and, :or, :[], :[]=, :columns, :columns!]
|
76
76
|
|
77
77
|
# Class instance variables to set to nil when a subclass is created, for -w compliance
|
78
78
|
EMPTY_INSTANCE_VARIABLES = [:@overridable_methods_module, :@db]
|
@@ -1438,6 +1438,12 @@ module Sequel
|
|
1438
1438
|
super
|
1439
1439
|
end
|
1440
1440
|
|
1441
|
+
# Clear the associations cache when refreshing
|
1442
|
+
def set_values(hash)
|
1443
|
+
@associations.clear if @associations
|
1444
|
+
super
|
1445
|
+
end
|
1446
|
+
|
1441
1447
|
# Formally used internally by the associations code, like pk but doesn't raise
|
1442
1448
|
# an Error if the model has no primary key. Not used any longer, deprecated.
|
1443
1449
|
def pk_or_nil
|
@@ -1510,12 +1516,6 @@ module Sequel
|
|
1510
1516
|
end
|
1511
1517
|
end
|
1512
1518
|
|
1513
|
-
# Clear the associations cache when refreshing
|
1514
|
-
def _refresh(dataset)
|
1515
|
-
associations.clear
|
1516
|
-
super
|
1517
|
-
end
|
1518
|
-
|
1519
1519
|
# Add the given associated object to the given association
|
1520
1520
|
def add_associated_object(opts, o, *args)
|
1521
1521
|
klass = opts.associated_class
|
@@ -1833,13 +1833,14 @@ module Sequel
|
|
1833
1833
|
opt = opt ? opt.dup : {}
|
1834
1834
|
associations.flatten.each do |association|
|
1835
1835
|
case association
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1836
|
+
when Symbol
|
1837
|
+
check_association(model, association)
|
1838
|
+
opt[association] = nil
|
1839
|
+
when Hash
|
1840
|
+
association.keys.each{|assoc| check_association(model, assoc)}
|
1841
|
+
opt.merge!(association)
|
1842
|
+
else
|
1843
|
+
raise(Sequel::Error, 'Associations must be in the form of a symbol or hash')
|
1843
1844
|
end
|
1844
1845
|
end
|
1845
1846
|
clone(:eager=>opt)
|
@@ -1956,7 +1957,8 @@ module Sequel
|
|
1956
1957
|
ds = ds.eager_graph_association(ds, model, ta, requirements, eager_graph_check_association(model, assoc), assoc_assocs)
|
1957
1958
|
end
|
1958
1959
|
ds
|
1959
|
-
else
|
1960
|
+
else
|
1961
|
+
raise(Sequel::Error, 'Associations must be in the form of a symbol or hash')
|
1960
1962
|
end
|
1961
1963
|
end
|
1962
1964
|
ds
|
data/lib/sequel/model/base.rb
CHANGED
@@ -869,6 +869,9 @@ module Sequel
|
|
869
869
|
# Define instance method(s) that calls class method(s) of the
|
870
870
|
# same name, caching the result in an instance variable. Define
|
871
871
|
# standard attr_writer method for modifying that instance variable.
|
872
|
+
#
|
873
|
+
# Do not call this method with untrusted input, as that can result in
|
874
|
+
# arbitrary code execution.
|
872
875
|
def self.class_attr_overridable(*meths) # :nodoc:
|
873
876
|
meths.each{|meth| class_eval("def #{meth}; !defined?(@#{meth}) ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)}
|
874
877
|
attr_writer(*meths)
|
@@ -878,6 +881,9 @@ module Sequel
|
|
878
881
|
# same name. Replaces the construct:
|
879
882
|
#
|
880
883
|
# define_method(meth){self.class.send(meth)}
|
884
|
+
#
|
885
|
+
# Do not call this method with untrusted input, as that can result in
|
886
|
+
# arbitrary code execution.
|
881
887
|
def self.class_attr_reader(*meths) # :nodoc:
|
882
888
|
meths.each{|meth| class_eval("def #{meth}; self.class.#{meth} end", __FILE__, __LINE__)}
|
883
889
|
end
|
@@ -1187,7 +1193,7 @@ module Sequel
|
|
1187
1193
|
end
|
1188
1194
|
end
|
1189
1195
|
|
1190
|
-
# Returns a hash
|
1196
|
+
# Returns a hash mapping the receivers primary key column(s) to their values.
|
1191
1197
|
#
|
1192
1198
|
# Artist[1].pk_hash # => {:id=>1}
|
1193
1199
|
# Artist[[1, 2]].pk_hash # => {:id1=>1, :id2=>2}
|
@@ -1983,7 +1989,7 @@ module Sequel
|
|
1983
1989
|
end
|
1984
1990
|
|
1985
1991
|
# Given a primary key value, return the first record in the dataset with that primary key
|
1986
|
-
# value.
|
1992
|
+
# value. If no records matches, returns nil.
|
1987
1993
|
#
|
1988
1994
|
# # Single primary key
|
1989
1995
|
# Artist.dataset.with_pk(1) # SELECT * FROM artists WHERE (id = 1) LIMIT 1
|
@@ -1994,6 +2000,12 @@ module Sequel
|
|
1994
2000
|
def with_pk(pk)
|
1995
2001
|
first(model.qualified_primary_key_hash(pk))
|
1996
2002
|
end
|
2003
|
+
|
2004
|
+
# Same as with_pk, but raises NoMatchingRow instead of returning nil if no
|
2005
|
+
# row matches.
|
2006
|
+
def with_pk!(pk)
|
2007
|
+
with_pk(pk) || raise(NoMatchingRow)
|
2008
|
+
end
|
1997
2009
|
end
|
1998
2010
|
|
1999
2011
|
extend ClassMethods
|
@@ -148,10 +148,10 @@ module Sequel
|
|
148
148
|
end
|
149
149
|
|
150
150
|
module InstanceMethods
|
151
|
-
# Clear the cached compositions when
|
152
|
-
def
|
151
|
+
# Clear the cached compositions when setting values.
|
152
|
+
def set_values(hash)
|
153
|
+
@compositions.clear if @compositions
|
153
154
|
super
|
154
|
-
compositions.clear
|
155
155
|
end
|
156
156
|
|
157
157
|
# For each composition, set the columns in the model class based
|
data/lib/sequel/plugins/dirty.rb
CHANGED
@@ -115,6 +115,12 @@ module Sequel
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
# Reset the initial values when setting values.
|
119
|
+
def set_values(hash)
|
120
|
+
reset_initial_values
|
121
|
+
super
|
122
|
+
end
|
123
|
+
|
118
124
|
# Manually specify that a column will change. This should only be used
|
119
125
|
# if you plan to modify a column value in place, which is not recommended.
|
120
126
|
#
|
@@ -157,12 +163,6 @@ module Sequel
|
|
157
163
|
@previous_changes = column_changes
|
158
164
|
end
|
159
165
|
|
160
|
-
# Reset the initial values when refreshing.
|
161
|
-
def _refresh(dataset)
|
162
|
-
super
|
163
|
-
reset_initial_values
|
164
|
-
end
|
165
|
-
|
166
166
|
# When changing the column value, save the initial column value. If the column
|
167
167
|
# value is changed back to the initial value, update changed columns to remove
|
168
168
|
# the column.
|
@@ -69,6 +69,9 @@ module Sequel
|
|
69
69
|
# # move MyModel object to there
|
70
70
|
# end
|
71
71
|
# end
|
72
|
+
#
|
73
|
+
# Do not call this method with untrusted input, as that can result in
|
74
|
+
# arbitrary code execution.
|
72
75
|
def add_hook_type(*hooks)
|
73
76
|
Model::HOOKS.concat(hooks)
|
74
77
|
hooks.each do |hook|
|
@@ -168,35 +168,25 @@ module Sequel
|
|
168
168
|
end
|
169
169
|
|
170
170
|
module InstanceMethods
|
171
|
-
# Hash of deserialized values, used as a cache.
|
172
|
-
attr_reader :deserialized_values
|
173
|
-
|
174
|
-
# Set @deserialized_values to the empty hash
|
175
|
-
def initialize_set(values)
|
176
|
-
@deserialized_values = {}
|
177
|
-
super
|
178
|
-
end
|
179
|
-
|
180
171
|
# Serialize deserialized values before saving
|
181
172
|
def before_save
|
182
173
|
serialize_deserialized_values
|
183
174
|
super
|
184
175
|
end
|
185
176
|
|
186
|
-
#
|
187
|
-
def
|
177
|
+
# Hash of deserialized values, used as a cache.
|
178
|
+
def deserialized_values
|
188
179
|
@deserialized_values ||= {}
|
189
|
-
super
|
190
180
|
end
|
191
181
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
def _refresh(*)
|
196
|
-
@deserialized_values = {}
|
182
|
+
# Initialization the deserialized values for objects retrieved from the database.
|
183
|
+
def set_values(hash)
|
184
|
+
@deserialized_values.clear if @deserialized_values
|
197
185
|
super
|
198
186
|
end
|
199
187
|
|
188
|
+
private
|
189
|
+
|
200
190
|
# Deserialize the column value. Called when the model column accessor is called to
|
201
191
|
# return a deserialized value.
|
202
192
|
def deserialize_value(column, v)
|