| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
| |
Previosly, `update_columns` would just take whatever keys you gave it
and tried to run the update query. Most likely this would result in an
error from the database. However, if the column actually did exist, but
was in `ignored_columns`, this would result in the method returning
successfully when it should have raised, and an attribute that should
not exist written to `@attributes`.
|
|
|
|
| |
See https://english.stackexchange.com/questions/23218/anyone-has-or-anyone-have-seen-them
|
| |
|
|
|
|
|
|
|
|
| |
Ruby uses the original method name, so will show the __temp__ method
name in the backtrace. However, in the common case the method name
is compatible with the `def` keyword, so we can avoid the __temp__
method name in that case to improve the name shown in backtraces
or TracePoint#method_id.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since Rails 6.0 will support Ruby 2.4.1 or higher
`# frozen_string_literal: true` magic comment is enough to make string object frozen.
This magic comment is enabled by `Style/FrozenStringLiteralComment` cop.
* Exclude these files not to auto correct false positive `Regexp#freeze`
- 'actionpack/lib/action_dispatch/journey/router/utils.rb'
- 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb'
It has been fixed by https://github.com/rubocop-hq/rubocop/pull/6333
Once the newer version of RuboCop released and available at Code Climate these exclude entries should be removed.
* Replace `String#freeze` with `String#-@` manually if explicit frozen string objects are required
- 'actionpack/test/controller/test_case_test.rb'
- 'activemodel/test/cases/type/string_test.rb'
- 'activesupport/lib/active_support/core_ext/string/strip.rb'
- 'activesupport/test/core_ext/string_ext_test.rb'
- 'railties/test/generators/actions_test.rb'
|
|\
| |
| | |
Improve error message when assign wrong attributes to model
|
| | |
|
|\ \
| | |
| | | |
Fix non_numeric_string?
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
For example, dirty checking was not right for the following case:
```
model.int_column = "+5"
model.float_column = "0.5E+1"
model.decimal_column = "0.5e-3"
```
It is enough to see whether leading character is a digit for avoiding
invalid numeric expression like 'wibble' to be type-casted to 0, as
this method's comment says.
Fixes #33801
|
|\ \ \
| |/ /
|/| |
| | |
| | | |
Larochelle/i18n_full_message_with_nested_attributes
`ActiveModel.full_message` interaction with `index_errors`
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The multiplication of the value takes a long time when we can instead mutate and use the string value directly.
The `microsec` perf increases speed by 27% in the ideal case (which is the most common).
```
original_string = ".443959"
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("multiply") {
string = original_string.dup
(string.to_r * 1_000_000).to_i
}
x.report("new ") {
string = original_string.dup
if string && string.start_with?(".".freeze) && string.length == 7
string[0] = ''.freeze
string.to_i
end
}
x.compare!
end
# Warming up --------------------------------------
# multiply 125.783k i/100ms
# new 146.543k i/100ms
# Calculating -------------------------------------
# multiply 1.751M (± 3.3%) i/s - 8.805M in 5.033779s
# new 2.225M (± 2.1%) i/s - 11.137M in 5.007110s
# Comparison:
# new : 2225289.7 i/s
# multiply: 1751254.2 i/s - 1.27x slower
```
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Record
The purpose of fe9547b is to work type casting to value from database.
But that was caused not to use the value before type cast even except
Active Record.
There we never guarantees that the value before type cast was going to
the used in this validation, but we should not change the behavior
unless there is some particular reason.
To restore original behavior, still use the value before type cast if
`came_from_user?` is undefined (i.e. except Active Record).
Fixes #33651.
Fixes #33686.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Since fe9547b6, numericality validator would parse raw value only when a
value came from user to work type casting to a value from database.
But that was caused a regression that the validator would work against
getter value instead of parsed raw value, a getter is sometimes
customized by people. #33550
There we never guarantees that the value before type cast was going to
the used in this validation (actually here is only place that getter
value might not be used), but we should not change the behavior unless
there is some particular reason.
The purpose of fe9547b6 is to work type casting to a value from
database. We could achieve the purpose by using `read_attribute`,
without using getter value.
Fixes #33550.
|
|\ \
| | |
| | | |
Fix AM::Serializers::JSON#as_json method for timestamps
|
| | |
| | |
| | |
| | |
| | | |
According to doc the method should return
non-json compatible types as strings.
|
| | |
| | |
| | | |
The purpose of the module seems to quack like a string.
|
|\ \ \
| | | |
| | | |
| | | | |
Add strict argument checking to ActiveRecord callbacks
|
|/ / /
| | |
| | |
| | | |
This ends up adding it to all save-related callbacks defined in `ActiveRecord::DefineCallbacks`, including e.g. `after_create`. Which should be fine: they didn't support `:on` in the first place.
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | | |
Since we have `has_secure_token`, it is too confusing to use `_token`
suffix with `has_secure_password`.
Context https://github.com/rails/rails/pull/33307#discussion_r200807185
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
See https://github.com/rails/rails/commit/136fc65c9b8b66e1fb56f3a17f0d1fddff9b4bd0#r28897107
I _think_ that this method can now be rewritten from:
```ruby
def attribute_previous_change(attr)
previous_changes[attr] if attribute_previously_changed?(attr)
end
```
to:
```ruby
def attribute_previous_change(attr)
previous_changes[attr]
end
```
without losing performance.
---
Calling
```ruby
previous_changes[attr] if attribute_previously_changed?(attr)
```
is equivalent to calling
```ruby
previous_changes[attr] if previous_changes.include?(attr)
```
When this commit 136fc65c9b was made, Active Record had its own `previous_changes` method, added here below. However, that method has been recently removed from the codebase, so `previous_changes` is now only the method defined in Active Model as:
```ruby
def previous_changes
@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new
@previously_changed.merge(mutations_before_last_save.changes)
end
```
Since we are dealing with a memoized Hash, there is probably no need to check `if .include?(attr_name)` before trying to fetch `[attr]` for it.
Does that make sense? Did I miss anything? Thanks!
|
|\ \ \
| | | |
| | | |
| | | | |
Allow configurable attribute name on `#has_secure_password`
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This change now creates a method `#authenticate_XXX` where XXX is
the configured attribute name on `#has_secure_password`. `#authenticate`
is now an alias to this method when the attribute name is the default
'password'
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
existing `#has_secure_password`. This can be useful when one would
like to store some secure field as a digest, just like a password.
The method still defaults to `password`. It now also allows using the
same `#authenticate` method which now accepts a second argument for
specifying the attribute to be authenticated, or will default to 'password`.
A new method is also added for generating a new token for an attribute by
calling `#regenerate_XXXX` where `XXXX` is the attribute name.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
- Fix indentation.
- Add a missing dot to the end of the sentence.
Related to #32956
|
|\ \ \ \
| | | | |
| | | | | |
Allow to override the full_message error format
|
| | | | | |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
When requesting columns names from database adapters AR:Result
would dup/freeze column names, this prefers using fstrings which
cuts down on repeat allocations
Attributes that are retained keep these fstrings around for the long
term
Note, this has the highest impact on "short" result sets, eg: Topic.first where you can void allocating the number of columns * String.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`QueryAttribute#value_for_database` calls only `type.serialize`, and
`Boolean#serialize` is a no-op unlike other attribute types.
It caused the issue #32624. Whether or not `serialize` will invoke
`cast` is undefined in our test cases, but it actually does not work
properly unless it does so for now.
Fixes #32624.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Since `parse_raw_value_as_a_number` may not always parse raw value from
database as a number without type casting (e.g. "$150.55" as money
format).
Fixes #32531.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Since #26074, introduced force equality checking to build a predicate
consistently for both `find` and `create` (fixes #27313).
But the assumption that only array/range attribute have subtype was
wrong. We need to make force equality checking more strictly not to
allow serialized attribute.
Fixes #32761.
|
| | | | |
| | | | |
| | | | |
| | | | | |
Before it was coercing an invalid string into "2000-01-01 00:00:00".
|
| |_|_|/
|/| | |
| | | |
| | | | |
Inside user_input_in_time_zone we call in_time_zone on the value and value can be a String.
|
|/ / / |
|
| | | |
|
| | | |
|
|\ \ \
| | | |
| | | | |
Prevent changes_to_save from mutating attributes
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
When an array of hashes is added to a `HashWithIndifferentAccess`, the
hashes are replaced with HWIAs by mutating the array in place.
If an attribute's value is an array of hashes, `changes_to_save` will
convert it to an array of HWIAs as a side-effect of adding it to the
changes hash.
Using `merge!` instead of `[]=` fixes the problem, as `merge!` copies
any array values in the provided hash instead of mutating them.
|
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
`changed_attribute_names_to_save` is called in `keys_for_partial_write`,
which is called on every save when partial writes are enabled.
We can avoid generating the full changes hash by asking the mutation
tracker for just the names of the changed attributes. At minimum this
saves one array allocation per attribute, but will also avoid calling
`Attribute#original_value` which is expensive for serialized attributes.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
For legacy reasons Rails stores time columns on sqlite as full
timestamp strings. However because the date component wasn't being
normalized this meant that when they were read back they were being
prefixed with 2001-01-01 by ActiveModel::Type::Time. This had a
twofold result - first it meant that the fast code path wasn't being
used because the string was invalid and second it was corrupting the
second fractional component being read by the Date._parse code path.
Fix this by a combination of normalizing the timestamps on writing
and also changing Active Model to be more lenient when detecting
whether a string starts with a date component before creating the
dummy time value for parsing.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
In #20317, datetime columns had their precision applied on assignment but
that behaviour wasn't applied to time columns - this commit fixes that.
Fixes #30301.
|
| | |
| | |
| | |
| | |
| | |
| | | |
This is an alternate implementation of #31698. That PR makes assumptions
that I do not want in the code base. We can fix the performance
regression with a much simpler patch.
|
| | |
| | |
| | |
| | | |
This reverts commit a19e91f0fab13cca61acdb1f33e27be2323b9786.
|
| | |
| | |
| | |
| | |
| | | |
https://bugs.ruby-lang.org/issues/12752
https://ruby-doc.org/core-2.4.0/String.html#method-i-unpack1
|
| | |
| | |
| | |
| | | |
There is no reason `attributes=` doesn't take `assign_attributes`.
|
|\ \ \
| | | |
| | | | |
Add ActiveModel::Attributes#attributes
|