- 27 1月, 2015 7 次提交
-
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
All of its uses have been moved to better places
-
由 Sean Griffin 提交于
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]
-
由 Sean Griffin 提交于
The Relation will ultimately end up holding a reference to the arel table object, and its associated type caster. If this is a `TypeCaster::Connection`, that means it'll hold a reference to the connection adapter, which cannot be marshalled. We can work around this by just holding onto the class object instead. It's ugly, but I'm hoping to remove the need for the connection adapter type caster in the future anyway. [Sean Griffin & anthonynavarre]
-
由 Sean Griffin 提交于
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]
-
由 Sean Griffin 提交于
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]
-
由 Sean Griffin 提交于
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
-
- 26 1月, 2015 16 次提交
-
-
由 Carlos Antonio da Silva 提交于
It's under private in Active Model as well.
-
由 Sean Griffin 提交于
We've now removed all uses of them across the board. All logic lives on `WhereClause`.
-
由 Sean Griffin 提交于
The code assumes that non-single-value methods mean multi value methods. That is not the case. We need to change the accessor name, and only assign an array for multi value methods
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
We're still using it in `where_unscoping`, which will require moving additional logic.
-
由 Sean Griffin 提交于
This will make it easy to add `having_clause` and `join_clause` later.
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
Yes, I know, I called it a factory so I'm basically the worst person ever who loves Java and worships the Gang of Four.
-
由 Sean Griffin 提交于
-
由 Sean Griffin 提交于
Bind values are no longer a thing, so this is unnecessary.
-
由 Sean Griffin 提交于
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`
-
由 Sean Griffin 提交于
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.
-
由 Sean Griffin 提交于
See 4d7a6229 for the reasoning
-
由 Sean Griffin 提交于
The structure of `values[:where]` is going to change, with an intermediate definition of `where_values` to aid the refactoring. Accessing `values[:where]` directly messes with that, signficantly. The array wrapping is no longer necessary, since `where_values` will always return an array.
-
- 25 1月, 2015 5 次提交
-
-
由 Rémy Coutable 提交于
[ci skip]
-
由 Sean Griffin 提交于
This will allow all types which require no additional handling to use prepared statements. Specifically, this will allow for `true`, `false`, `Date`, `Time`, and any custom PG type to use prepared statements. This also revealed another source of nil columns in bind params, and an inconsistency in their use. The specific inconsistency comes from a nested query coming from a through association, where one of the inversed associations is not bi-directional. The stop-gap is to simply construct the column at the site it is being used. This should simply go away on its own once we use `Attribute` to represent them instead, since we already have all of the information we need.
-
由 Sean Griffin 提交于
This is to help facilitate future refactorings, as the internal representation is changed. I'm planning on having `where_values` return an array that's computed on call, which means that mutation will have no affect. This is the only remaining place that was mutating (tested by replacing the method with calling `dup`)
-
由 Sean Griffin 提交于
Specifically, the issue is relying on `where_unscoping` mutating the where values. It does not, however, mutate the bind values, which could cause an error under certain circumstances. This was not exposed by the tests, since the only place which would have been affected is unscoping a boolean, which doesn't go through prepared statements. I had a hard time getting better test coverage to demonstrate the issue. This in turn, caused `merge` to go through proper logic, and try to clear out the binds associated with the unscoped relation, which then exposed a source of `nil` for the columns, as binds weren't expanding `{ "posts.id" => 1 }` to `{ "posts" => { "id" => 1 } }`. This has been fixed. The bulk of `create_binds` needed to be moved to a separate method, since the dot notation should not be expanded recursively. I'm pretty sure this removes a subtle quirk that a ton of code in `Relation::Merger` is working around, and I suspect that code can be greatly simplified. However, unraveling that rats nest is no small task.
-
由 Sean Griffin 提交于
-
- 24 1月, 2015 5 次提交
-
-
由 Sean Griffin 提交于
Minor style changes across the board. Changed an alias to an explicit method declaration, since the alias will not be documented otherwise.
-
由 Bogdan Gusiev 提交于
Allows to use it for any object as an includable module.
-
由 Sean Griffin 提交于
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
-
由 Sean Griffin 提交于
Fixes #18580.
-
由 Sean Griffin 提交于
Fixes #18632
-
- 23 1月, 2015 1 次提交
-
-
由 Santosh Wadghule 提交于
-
- 22 1月, 2015 1 次提交
-
-
由 Sean Griffin 提交于
Keeping with our behavior elsewhere in the system, invalid input is assumed to be `nil`. Fixes #18629.
-
- 21 1月, 2015 3 次提交
-
-
由 Santosh Wadghule 提交于
-
由 Sean Griffin 提交于
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 ```
-
由 Arthur Neves 提交于
-
- 20 1月, 2015 2 次提交
-
-
由 Sean Griffin 提交于
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)
-
由 Sean Griffin 提交于
I'm looking to introduce a `WhereClause` class to handle most of this logic, and this method will eventually move over to there. However, this intermediate refactoring should make that easier to do.
-