| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The `&block` form is more than twice as fast as the manual form of
delegation (and is the code I'd rather write anyway). Unfortunately,
it's still twice as slow on MRI. However, this is enough of a hotspot to
justify giving JRuby special treatment.
I can't currently provide benchmarks in the context of Active Record,
since the JDBC adapters still aren't updated for 4.2, but the actual
work performed (assuming it's been read at least once already) will have
nearly the same performance characteristics as
https://gist.github.com/sgrif/b86832786551aaee74de.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It's finally finished!!!!!!! The reason the Attributes API was kept
private in 4.2 was due to some publicly visible implementation details.
It was previously implemented by overloading `columns` and
`columns_hash`, to make them return column objects which were modified
with the attribute information.
This meant that those methods LIED! We didn't change the database
schema. We changed the attribute information on the class. That is
wrong! It should be the other way around, where schema loading just
calls the attributes API for you. And now it does!
Yes, this means that there is nothing that happens in automatic schema
loading that you couldn't manually do yourself. (There's still some
funky cases where we hit the connection adapter that I need to handle,
before we can turn off automatic schema detection entirely.)
There were a few weird test failures caused by this that had to be
fixed. The main source came from the fact that the attribute methods are
now defined in terms of `attribute_names`, which has a clause like
`return [] unless table_exists?`. I don't *think* this is an issue,
since the only place this caused failures were in a fake adapter which
didn't override `table_exists?`.
Additionally, there were a few cases where tests were failing because a
migration was run, but the model was not reloaded. I'm not sure why
these started failing from this change, I might need to clear an
additional cache in `reload_schema_from_cache`. Again, since this is not
normal usage, and it's expected that `reset_column_information` will be
called after the table is modified, I don't think it's a problem.
Still, test failures that were unrelated to the change are worrying, and
I need to dig into them further.
Finally, I spent a lot of time debugging issues with the mutex used in
`define_attribute_methods`. I think we can just remove that method
entirely, and define the attribute methods *manually* in the call to
`define_attribute`, which would simplify the code *tremendously*.
Ok. now to make this damn thing public, and work on moving it up to
Active Model.
|
|
|
|
|
|
| |
Remaining are `limit`, `precision`, `scale`, and `type` (the symbol
version). These will remain on the column, since they mirror the options
to the `column` method in the schema definition DSL
|
|\
| |
| | |
[ci skip] fix typo still -> will
|
| | |
|
|/
|
|
| |
Fixes #18580.
|
|
|
|
|
|
|
|
|
|
|
| |
When an attribute is assigned, we determine if it was already marked as
changed so we can determine if we need to clear the changes, or mark it
as changed. Since this only affects the `attributes_changed_by_setter`
hash, in-place changes are irrelevant to this process. Since calculating
in-place changes can be expensive, we can just skip it here.
I also added a test for the only edge case I could think of that would
be affected by this change.
|
| |
|
|
|
|
|
|
| |
The types that are affected by `time_zone_aware_attributes` (which is on
by default) have been made configurable, in case this is a breaking
change for existing applications.
|
|
|
|
|
|
| |
While we don't want to change the form input when validations fail,
blindly using `_before_type_cast` will cause the input to display the
wrong data for any type which does additional work on database values.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This sets a precident for how we handle `attribute` calls, which aren't
backed by a database column. We should not take this as a conscious
decision on how to handle them, and this can change when we make
`attribute` public if we have better ideas in the future.
As the composed attributes API gets fleshed out, I expect the
`persistable_attributes` method to change to
`@attributes.select(&:persistable).keys`, or some more performant
variant there-of. This can probably go away completely once we fully
move dirty checking into the attribute objects once it gets moved up to
Active Model.
Fixes #18407
|
|
|
|
| |
ref #52f641264b1325a4c2bdce7971b14524bd4905f1
|
| |
|
|
|
|
|
| |
Conflicts:
activerecord/lib/active_record/attribute_methods/read.rb
|
|
|
|
| |
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.
|