| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
Contrary to my previous commit message, it wasn't overkill, and led to
much cleaner code.
[Sean Griffin & anthonynavarre]
|
|
|
|
|
|
|
|
|
|
| |
The last place that was assigning it was when `from` is called with a
relation to use as a subquery. The implementation was actually
completely broken, and would break if you called `from` more than once,
or if you called it on a relation, which also had its own join clause,
as the bind values would get completely scrambled. The simplest solution
was to just move it into its own array, since creating a `FromClause`
class for this would be overkill.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This removes the need to duplicate much of the logic in `WhereClause`
and `PredicateBuilder`, simplifies the code, removes the need for the
connection adapter to be continuously passed around, and removes one
place that cares about the internal representation of `bind_values`
Part of the larger refactoring to change how binds are represented
internally
[Sean Griffin & anthonynavarre]
|
|
|
|
|
|
| |
PG expects us to not give it nonsenes
[Sean Griffin & anthonynavarre]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixed an issue where `having` can only be called after the last
call to `where`, because it messes with the same `bind_values` array.
With this change, the two can be called as many times as needed, in any
order, and the final query will be correct. However, once something
assigns `bind_values`, that stops. This is because we have to move all
of the bind values from the having clause over to the where clause since
we can't differentiate the two, and assignment was likely in the form
of:
`relation.bind_values += other.bind_values`
This will go away once we remove all places that are assigning
`bind_values`, which is next on the list.
While this fixes a bug that was present in at least 4.2 (more likely
present going back as far as 3.0, becoming more likely in 4.1 and later
as we switched to prepared statements in more cases), I don't think this
can be easily backported. The internal changes to `Relation` are
non-trivial, anything that involves modifying the `bind_values` array
would need to change, and I'm not confident that we have sufficient test
coverage of all of those locations (when `having` was called with a hash
that could generate bind values).
[Sean Griffin & anthonynavarre]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When we made sure that the counter gets updated in memory, we only did
it on the has many side. The has many side only does the update if the
belongs to cannot. The belongs to side was updated to update the counter
cache (if it is able). This means that we need to check if the
belongs_to is able to update in memory on the has_many side.
We also found an inconsistency where the reflection names were used to
grab the association which should update the counter cache. Since
reflection names are now strings, this means it was using a different
instance than the one which would have the inverse instance set.
Fixes #18689
[Sean Griffin & anthonynavarre]
|
| |
|
|
|
|
|
|
|
|
|
| |
There are many ways that things end up getting passed to `concat`. Not
all of those entry points called `flatten` on their input. It seems that
just about every method that is meant to take a single record, or that
splats its input, is meant to also take an array. `concat` is the
earliest point that is common to all of the methods which add records to
the association. Partially fixes #18689
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
This object being a black box, it knows the details of how to merge
itself with another where clause. This removes all references to where
values or bind values in `Relation::Merger`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The way that bind values are currently stored on Relation is a mess.
They can come from `having`, `where`, or `join`. I'm almost certain that
`having` is actually broken, and calling `where` followed by `having`
followed by `where` will completely scramble the binds.
Joins don't actually add the bind parameters to the relation itself, but
instead add it onto an accessor on the arel AST which is undocumented,
and unused in Arel itself. This means that the bind values must always
be accessed as `relation.arel.bind_values + relation.bind_values`.
Anything that doesn't is likely broken (and tons of bugs have come up
for exactly that reason)
The result is that everything dealing with `Relation` instances has to
know far too much about the internals. The binds are split, combined,
and re-stored in non-obvious ways that makes it difficult to change
anything about the internal representation of `bind_values`, and is
extremely prone to bugs.
So the goal is to move a lot of logic off of `Relation`, and into
separate objects. This is not the same as what is currently done with
`JoinDependency`, as `Relation` knows far too much about its internals,
and vice versa. Instead these objects need to be black boxes that can
have their implementations swapped easily.
The end result will be two classes, `WhereClause` and `JoinClause`
(`having` will just re-use `WhereClause`), and there will be a single
method to access the bind values of a `Relation` which will be
implemented as
```
join_clause.binds + where_clause.binds + having_clause.binds
```
This is the first step towards that refactoring, with the internal
representation of where changed, and an intermediate representation of
`where_values` and `bind_values` to let the refactoring take small
steps. These will be removed shortly.
|
|\
| |
| |
| | |
pretty_print will use #inspect if a subclass redefines it
|
| | |
|
| | |
|
|\ \
| | |
| | |
| | | |
Extracted attributes assingment from ActiveRecord to ActiveModel
|
| | |
| | |
| | |
| | |
| | |
| | | |
`ActiveModel::AttributesAssignment`
Allows to use it for any object as an includable module.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Given that this was originally added to normalize an error that would
have otherwise come from the database (inconsistently), it's more
natural for us to raise in `type_cast_for_database`, rather than
`type_cast_from_user`. This way, things like numericality validators can
handle it instead if the user chooses to do so. It also fixes an issue
where assigning an out of range value would make it impossible to assign
a new value later.
This fixes several vague issues, none of which were ever directly
reported, so I have no issue number to give. Places it was mentioned
which I can remember:
- https://github.com/thoughtbot/shoulda-matchers/blob/9ba21381d7caf045053a81f32df7de2f49687820/lib/shoulda/matchers/active_model/allow_value_matcher.rb#L261-L263
- https://github.com/rails/rails/issues/18653#issuecomment-71197026
|
| | |
| | |
| | |
| | | |
Fixes #18580.
|
|/ /
| |
| |
| | |
Fixes #18632
|
| |
| |
| |
| |
| |
| |
| | |
Keeping with our behavior elsewhere in the system, invalid input is
assumed to be `nil`.
Fixes #18629.
|
| |
| |
| |
| |
| |
| |
| | |
`drop_table`
since 'drop table if exists' statement does not always work with some databases such as Oracle.
also Oracle drop table statement will not drop sequence objects.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This method can be used to see all of the fields on a model which have
been read. This can be useful during development mode to quickly find
out which fields need to be selected. For performance critical pages, if
you are not using all of the fields of a database, an easy performance
win is only selecting the fields which you need. By calling this method
at the end of a controller action, it's easy to determine which fields
need to be selected.
While writing this, I also noticed a place for an easy performance win
internally which I had been wanting to introduce. You cannot mutate a
field which you have not read. Therefore, we can skip the calculation of
in place changes if we have never read from the field. This can
significantly speed up methods like `#changed?` if any of the fields
have an expensive mutable type (like `serialize`)
```
Calculating -------------------------------------
#changed? with serialized column (before)
391.000 i/100ms
#changed? with serialized column (after)
1.514k i/100ms
-------------------------------------------------
#changed? with serialized column (before)
4.243k (± 3.7%) i/s - 21.505k
#changed? with serialized column (after)
16.789k (± 3.2%) i/s - 84.784k
```
|
| | |
|
|\ \
| | |
| | | |
Support after_commit callbacks in transactional fixtures
|
| | |
| | |
| | |
| | |
| | |
| | | |
after_commit callbacks run after committing a transaction whose parent
is not `joinable?`: un-nested transactions, transactions within test
cases, and transactions in `console --sandbox`.
|
| | | |
|
|\ \ \
| | | |
| | | | |
Add an `:if_exists` option to `drop_table`
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
If set to `if_exists: true`, it generates a statement like:
DROP TABLE IF EXISTS posts
This syntax is supported in the popular SQL servers, that is (at least)
SQLite, PostgreSQL, MySQL, Oracle and MS SQL Sever.
Closes #16366.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
With the old implementation, the bind values were created, and then we
search the attributes for `Relation` objects, and merge them. This
completely ignores the order that the actual `where` clause will use. If
all non-relation where parameters are before the relations, it will
work. However, if we query on both a relation and a value, with the
value coming second, it breaks. The order of the hash should not affect
the final query (especially since hashes being ordered is an
implementation detail)
|
|/ / /
| | |
| | |
| | |
| | |
| | | |
Looking through the blame, this logic used to be when we actually
created the bind tuple. My guess is that `nil` couldn't be handled there
at that time. It can, now.
|
|\ \ \
| | | |
| | | | |
Remove unused accessor
|
| | | | |
|
|\ \ \ \
| |/ / /
|/| | | |
Run SQL only if attribute changed for update_attribute method
|
| | | |
| | | |
| | | |
| | | |
| | | | |
- This is based on https://github.com/rails/rails/issues/18400 but
tackling same issue with update_attribute method instead of update method.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
`.` is regexp meta character. It should be escape for `assert_match`
correctly.
|
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
|/ /
| |
| |
| | |
#assert was used when it should be assert_equal.
|
| |
| |
| |
| |
| |
| | |
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 behavior exists only to support fixtures, so we should handle it
there. Leaving it in `#quote` can cause very subtle bugs to slip
through, by things appearing to work when they should be blowing up
loudly, such as #18385.
|
|
|
|
|
|
|
| |
I'm planning on deprecating the column argument to mirror the
deprecation in [arel].
[arel]: https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
|
|
|
|
|
|
| |
There's very little value in logging "<NULL binary data>" instead of
just "nil". I'd like to remove the column from the equation entirely,
and this case is preventing us from doing so.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
| |
Update Secure Token Doc [ci skip]
remove require securerandom, core_ext/securerandom already do that ref 7e006057
|