Before 34cc301, type casting by boolean attribute when querying is a
no-op, so finding by truthy boolean string (i.e.
`where(value: "true") # => value = 'true'`) didn't work as expected
(matches it to FALSE in MySQL #32624). By type casting is ensured, a
value on boolean attribute is always serialized to TRUE or FALSE.
In PostgreSQL, `where(value: :false) # => value = 'false'` was a valid
SQL, so 34cc301 is a regresson for PostgreSQL since all symbol values
are serialized as TRUE.
I'd say using `:false` is mostly a developer's mistake (user's input
basically comes as a string), but `:false` on boolean attribute is
serialized as TRUE is not a desirable behavior for anybody.
This allows falsy boolean symbols as false, i.e.
`klass.create(value: :false).value? # => false` and
`where(value: :false) # => value = FALSE`.
Fixes#35676.
In Rails 5.2.x calling `has_secure_password` would define attribute
readers and writers on the superclass of the model, which meant that you
could override these attributes in a model and call the superclass for
example:
```
class Dog < ApplicationRecord
has_secure_password
def password=(new_password)
@password_set = new_password.present?
super
end
end
```
However this behaviour was broken in Rails 6 when the ability to
customise the name of the attribute was introduced [1] since they are no
longer being defined on the superclass you will now see the following
error:
```
NoMethodError:
super: no superclass method `password=' for #<Dog:0x00007ffbbc7ce290>
Did you mean? password
```
In order to resolve this issue and retain support for setting a custom
attribute name we can define these attribute readers/writers in a module
and then ensure that the module is included in the inheritance chain.
[1] https://www.github.com/rails/rails/commit/86a48b4da3https://www.github.com/rails/rails/commit/9b63bf1dfd
This reverts commit 52fddcc653.
52fddcc was to short-circuit `ensure_in_range` in `cast_value`. But that
caused a regression for empty string deserialization.
Since 7c6f393, `ensure_in_range` is moved into `serialize`. As 52fddcc
said, the absolute gain is quite small. So I've reverted that commit to
fix the regression.
This is a follow-up of #35310.
Currently `Topic.find_by(id: "not-a-number")` matches to a `id = 0`
record. That is considered as silently leaking information.
If non numeric string is given to find by an integer column, it should
not be matched to any record.
Related #12793.
That is considered as silently leaking information.
If type casting doesn't return any actual value, it should not be
matched to any record.
Fixes#33624.
Closes#33946.
Since `serialize` is passed user input args (from `where`, schema
default, etc), a helper should provide `serialize` if the helper also
provide `cast`.
Related #32624, 34cc301, a741208.
`value_from_multiparameter_assignment` defined by
`AcceptsMultiparameterTime` helper requires `default_timezone` method
which is defined at `TimeValue` helper.
Since `Date` type doesn't include `TimeValue`, I've extracted `Timezone`
helper to be shared by `Date`, `DateTime`, and `Time` types.
- If you had a PORO that acted like a Numeric, the validator would
work correctly because it was previously using `Kernel.Float`
which is implicitely calling `to_f` on the passed argument.
Since rails/rails@d126c0d , we are now using `BigDecimal` which does
not implicitely call `to_f` on the argument, making the validator
fail with an underlying `TypeError` exception.
This patch replate the `is_decimal?` check with `Kernel.Float`.
Using `Kernel.Float` as argument for the BigDecimal call has two
advantages:
1. It calls `to_f` implicetely for us.
2. It's also smart enough to detect that `Kernel.Float("a")` isn't a
Numeric and will raise an error.
We don't need the `is_decimal?` check thanks to that.
Passing `Float::DIG` as second argument to `BigDecimal` is mandatory
because the precision can't be omitted when passing a Float.
`Float::DIG` is what is used internally by ruby when calling
`123.to_d`
https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/lib/bigdecimal/util.rb#L47
- Another small issue introduced in https://github.com/rails/rails/pull/34693
would now raise a TypeError because `Regexp#===` will just return
false if the passed argument isn't a string or symbol, whereas
`Regexp#match?` will.
When assigning a hash to a time attribute that's missing a year
component (e.g. a `time_select` with `:ignore_date` set to `true`)
then the year defaults to 1970 instead of the expected 2000. This
results in the attribute changing as a result of the save.
Before:
event = Event.new(start_time: { 4 => 20, 5 => 30 })
event.start_time # => 1970-01-01 20:30:00 UTC
event.save
event.reload
event.start_time # => 2000-01-01 20:30:00 UTC
After:
event = Event.new(start_time: { 4 => 20, 5 => 30 })
event.start_time # => 2000-01-01 20:30:00 UTC
event.save
event.reload
event.start_time # => 2000-01-01 20:30:00 UTC
This file uses assert_valid_keys but it was not being required. You can
reproduce this error with a script that uses this feature by using those
requires:
require 'active_model'
require 'active_model/callbacks'
We had a discussion on the Core team and we don't want to expose this information
as a JSON endpoint and not by default.
It doesn't make sense to expose this JSON locally and this controller is only
accessible in dev, so the proposed access from a production app seems off.
This reverts commit 8eaffe7e89, reversing
changes made to b6e4305c3b.
Thanks to ko1, passing block parameter to another method is
significantly optimized in Ruby 2.5.
https://bugs.ruby-lang.org/issues/14045
Thus we no longer need to keep this ugly hack.
Generally followed the pattern for https://github.com/rails/rails/pull/32034
* Removes needless CI configs for 2.4
* Targets 2.5 in rubocop
* Updates existing CHANGELOG entries for fewer merge conflicts
* Removes Hash#slice extension as that's inlined on Ruby 2.5.
* Removes the need for send on define_method in MethodCallAssertions.
If a klass has acceptance validation and then
`klass.undefine_attribute_methods` is happened before an attribute
method is called, infinit loop is caused on the `method_missing` defined
by the `LazilyDefineAttributes`.
https://travis-ci.org/rails/rails/jobs/467053984#L1409
To prevent the infinit loop, the `method_missing` should ensure
`klass.define_attribute_methods`.