| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
| |
These requires were added only to change deprecation message
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
Calling `changed_attributes` will ultimately check if every mutable
attribute has changed in place. Since this gets called whenever an
attribute is assigned, it's extremely slow. Instead, we can avoid this
calculation until we actually need it.
Fixes #18029
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the case of serialized columns, we would expect the unserialized
value as input, not the serialized value. The original issue which made
this distinction, #14163, introduced a bug. If you passed serialized
input to the method, it would double serialize when it was sent to the
database. You would see the wrong input upon reloading, or get an error
if you had a specific type on the serialized column.
To put it another way, `update_column` is a special case of
`update_all`, which would take `['a']` and not `['a'].to_yaml`, but you
would not pass data from `params` to it.
Fixes #18037
|
|
|
|
|
|
|
|
|
|
|
|
| |
PostgreSQL for example, allows infinity as a valid value for date time
columns. The PG type has explicit handling for that case. However, time
zone conversion will end up trampling that handling. Unfortunately, we
can't call super and then convert time zones.
However, if we get back nil from `.in_time_zone`, it's something we
didn't expect so we can let the superclass handle it.
Fixes #17971
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The detection of in-place changes caused a weird unexpected issue with
numericality validations. That validator (out of necessity) works on the
`_before_type_cast` version of the attribute, since on an `:integer`
type column, a non-numeric string would type cast to 0.
However, strings are mutable, and we changed strings to ensure that the
post type cast version of the attribute was a different instance than
the before type cast version (so the mutation detection can work
properly).
Even though strings are the only mutable type for which a numericality
validation makes sense, special casing strings would feel like a strange
change to make here. Instead, we can make the assumption that for all
mutable types, we should work on the post-type-cast version of the
attribute, since all cases which would return 0 for non-numeric strings
are immutable.
Fixes #17852
|
|
|
|
|
|
|
| |
We added a comparison to "id", and call to `self.class.primary_key` a
*lot*. We also have performance hits from `&block` all over the place.
We skip the check in a new method, in order to avoid breaking the
behavior of `read_attribute`
|
| |
|
|
|
|
|
|
|
|
|
|
| |
We don't know which attributes will or won't be used, and we don't want
to create massive bottlenecks at instantiation. Rather than doing *any*
iteration over types and values, we can lazily instantiate the object.
The lazy attribute hash should not fully implement hash, or subclass
hash at any point in the future. It is not meant to be a replacement,
but instead implement its own interface which happens to overlap.
|
|
|
|
| |
There is a significant performance difference between the two. Closes
|
|
|
|
|
|
|
|
|
|
|
|
| |
The current style for warning messages without newlines uses
concatenation of string literals with manual trailing spaces
where needed.
Heredocs have better readability, and with `squish` we can still
produce a single line.
This is a similar use case to the one that motivated defining
`strip_heredoc`, heredocs are super clean.
|
| |
|
|
|
|
| |
/cc @sgrif
|
| |
|
|\
| |
| | |
use self instead of #read_attribute
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Using heredoc would enforce line wrapping to whatever column width we decided to
use in the code, making it difficult for the users to read on some consoles.
This does make the source code read slightly worse and a bit more error-prone,
but this seems like a fair price to pay since the primary purpose for these
messages are for the users to read and the code will not stick around for too
long.
|
|/
|
|
|
|
|
| |
`changes_applied` calles `changes`, which will call `changed_attributes`
multiple times in a loop. This method actually performs work now, so we
should cache the results while looping over it when we know it cannot
change.
|
|
|
|
|
|
| |
Now that `changed_attributes` includes in place changes, we don't need
to override these methods in Active Record. Partially fixes the
performance regression caused by #16189
|
| |
|
|
|
|
|
|
|
|
|
| |
Currently when we call id_was and we have a custom primary key name
Active Record will return the current value of the primary key. This
make impossible to correctly do an update operation if you change the
id.
Fixes #16413
|
|\
| |
| | |
Improve Active Model Dirty API.
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
#clear_changes_information
This method name is causing confusion with the `reset_#{attribute}`
methods. While `reset_name` set the value of the name attribute for the
previous value the `reset_changes` only discard the changes and previous
changes.
|
|/
|
|
|
|
|
| |
This reverts commit 6f3c64eeb1dc8288dae49f114aaf619adc7dcb7f.
Conflicts:
activerecord/CHANGELOG.md
|
|
|
|
|
|
| |
This reverts commit a03097759bd7103bb9db253e7ba095f011453f75.
This needs more work before it would work correctly on master.
|
|
|
|
|
|
|
|
| |
Fixed issue with ActiveRecord serialize object as JSON
Conflicts:
activerecord/CHANGELOG.md
activerecord/lib/active_record/attribute_methods/serialization.rb
|
|
|
|
|
|
|
|
| |
We are moving this behavior out to an object that we would like to keep
separated from `ActiveRecord::Base`, which means not passing the class
object to it. As such, we need to stop using `instance_exec`, and
instead close over the subclass on global type decorators that are
applied in `Base`.
|
|
|
|
|
|
| |
Making this change revealed several subtle bugs related to models with
no primary key, and anonymous classes. These have been fixed as well,
with regression tests added.
|
|
|
|
|
|
|
|
| |
This will make it less painful to add additional properties, which
should persist across writes, such as `name`.
Conflicts:
activerecord/lib/active_record/attribute_set.rb
|
|\
| |
| |
| |
| |
| |
| |
| | |
Move behavior of `read_attribute` to `AttributeSet`
Conflicts:
activerecord/lib/active_record/attribute_set.rb
activerecord/test/cases/attribute_set_test.rb
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Moved `Builder` to its own file, as it started looking very weird once I
added private methods to the `AttributeSet` class and the `Builder`
class started to grow.
Would like to refactor `fetch_value` to change to
```ruby
self[name].value(&block)
```
But that requires the attributes to know about their name, which they
currently do not.
|
|\ \
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Move `attributes_before_type_cast` to `AttributeSet`
Conflicts:
activerecord/lib/active_record/attribute_set.rb
activerecord/test/cases/attribute_set_test.rb
|
| | | |
|
| |/
|/|
| |
| |
| | |
We still had one file using `column_for_attribute` when it could return
nil, causing deprecation warnings in the tests.
|
|/ |
|
|
|
|
|
|
| |
We no longer need to "init changed attributes" from the initializer,
either, as there is no longer a case where a given value would differ
from the default, but would not already be marked as changed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This refactoring revealed the need for another form of decoration, which
takes a proc to select which it applies to (There's a *lot* of cases
where this form can be used). To avoid duplication, we can re-implement
the old decoration in terms of the proc-based decoration.
The reason we're `instance_exec`ing the matcher is for cases such as
time zone aware attributes, where a decorator is defined in a parent
class, and a method called in the matcher is overridden by a child
class. The matcher will close over the parent, and evaluate in its
context, which is not the behavior we want.
|
| |
|
|
|
|
| |
to "without replacement"
|
|
|
|
|
| |
We've stopped using it internally, in favor of polymorphism. So should
you!
|
|\
| |
| | |
Detect in-place changes on mutable AR attributes
|
| |
| |
| |
| |
| |
| | |
We have several mutable types on Active Record now. (Serialized, JSON,
HStore). We need to be able to detect if these have been modified in
place.
|
|\ \
| | |
| | | |
Introduce an Attribute object to handle the type casting dance
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
There's a lot more that can be moved to these, but this felt like a good
place to introduce the object. Plans are:
- Remove all knowledge of type casting from the columns, beyond a
reference to the cast_type
- Move type_cast_for_database to these objects
- Potentially make them mutable, introduce a state machine, and have
dirty checking handled here as well
- Move `attribute`, `decorate_attribute`, and anything else that
modifies types to mess with this object, not the columns hash
- Introduce a collection object to manage these, reduce allocations, and
not require serializing the types
|
| | |
|
|/
|
|
|
|
|
|
|
|
|
| |
We'd spend a lot of time calling `hash` and `eql?` on the join model,
which has no primary key. Calling `id` with no primary key is a really
slow way to get back `nil`, so we can improve the performance there.
However, even with the escape clause, we *still* weren't getting high
enough performance, as we were checking the primary key too much. `hash`
will always return `nil.hash` for records with no id, and `==` will
always return `false`. We can optimize those cases in the HABTM join
model.
|
|
|
|
|
|
|
|
|
|
| |
The original patch that added this concept can be found
[here](https://web.archive.org/web/20090601022739/http://dev.rubyonrails.org/ticket/9767).
The current default behavior is to cache everything except serialized
columns, unless the user specified otherwise. If anyone were to specify
otherwise, many types would actually be completely broken. Still, the
method is left in place with a deprecation warning in case anyone is
actually still calling this method.
|
|
|
|
|
|
|
|
| |
In some cases there is a difference between the two, we should always
be doing one or the other. For convenience, `type_cast` is still a
private method on type, so new types that do not need different behavior
don't need to implement two methods, but it has been moved to private so
it cannot be used accidentally.
|