Various behaviors needed by associations (such as creating the through
record) are lost when `where` is called, since we stop having a
`CollectionProxy` and start having an `AssociationRelation` which does
not contain this behavior. I *think* we should be able to rm
`AssociationRelation`, but we have tests saying the changes required to
do that would be bad (Without saying why. Of course. >_>)
Fixes#19073.
[Toby Ovod-Everett & Andrey Nering & Yves Senn]
Closes#17726.
Closes#10939.
This patch makes three distinct modifications:
1. no longer fall back to disabling user triggers if system triggers can't be disabled
2. warn the user when referential integrity can't be disabled
3. restore aborted transactions when referential integrity can't be disabled
The motivation behind these changes is to make the behavior of Rails
transparent and less error-prone. To require superuser privileges is not optimal
but it's what Rails currently needs. Users who absolutely rely on disabling user triggers
can patch `disable_referential_integrity`.
We should investigate `SET CONSTRAINTS` as a possible solution which does not require
superuser privileges.
/cc @matthewd
Fixes#18905. `#touch` now takes time as an option. Setting the option
saves the record with the updated_at/on attributes set to the current time
or the time specified. Updated tests and documentation accordingly.
This reverts commit 1502caefd30b137fd1a0865be34c5bbf85ba64c1.
The test suite for the mysql adapter broke when this commit was used
with MySQL 5.6.
Conflicts:
activerecord/CHANGELOG.md
Use SQL COUNT and LIMIT 1 queries for none? and one? methods if no block or limit is given,
instead of loading the entire collection to memory. The any? and many? methods already
follow this behavior.
[Eugene Gilburg & Rafael Mendonça França]
In addition to cleaning up the implementation, this allows type casting
behavior to be applied consistently everywhere. (#where for example). A
good example of this was the previous need for handling value to key
conversion in the setter, because the number had to be passed to `where`
directly. This is no longer required, since we can just pass the string
along to where. (It's left around for backwards compat)
Fixes#18387
It looks like the only reason `current_scope` was thread local on
`base_class` instead of `self` is to ensure that when we call a named
scope created with a proc on the parent class, it correctly uses the
default scope of the subclass. The reason this wasn't happening was
because the proc captured `self` as the parent class, and we're not
actually defining a real method. Using `instance_exec` fixes the
problem.
Fixes#18806
MySQL rejects to remove an index which is used in a foreign key constraint:
```
ActiveRecord::StatementInvalid: Mysql2::Error: Cannot drop index 'index_copies_on_title_id': needed in a foreign key constraint: ALTER TABLE `copies` DROP `title_id`
```
Removing the constraint before removing the column (and the index) solves this problem.
The charset of `version` column in `schema_migrations` table is depend
on the database default charset and collation rather than the encoding
of the connection.
While we query the proper columns, we go through normal handling for
converting the value to a primitive which assumes it should use the
table's primary key. If the association specifies a different value (and
we know that we're working with an association), we should use the
custom primary key instead.
Fixes#18813.
When ```becomes``` changes @attributes it should also change
@changed_attributes. Otherwise we'll experience a kind of split head situation
where attributes are coming from ```self```, but changed_attributes is coming
from ```klass.new```. This affects the inheritance_colmn as it's changed by new
for example.
Fixes#16881
The cache name should be converted to a string when given, not compared
as a symbol. This edge case is already adequately covered by our tests,
but was masked by another issue where we were incorrectly updating the
counter cache twice. When paired with a bug where we didn't update the
counter cache because we couldn't find a match with the name, this made
it look like everything was working fine.
Fixes#10865.
Fixes#17621. This 5 year old (or older) issue causes validations to fire
when a parent record has `validate: false` option and a child record is
saved. It's not the responsibility of the model to validate an
associated object unless the object was created or modified by the
parent.
Clean up tests related to validations
`assert_nothing_raised` is not benefiting us in these tests
Corrected spelling of "respects"
It's better to use `assert_not_operator` over `assert !r.valid`
* master:
Move required error message and changelog to Active Record
Use public Module#include, in favor of https://bugs.ruby-lang.org/issues/8846
Use Module#include instead of send :include, since now is a public method [ci skip]
✂️ warning from controller renderer test
Conflicts:
activerecord/CHANGELOG.md
These callbacks will already have been defined when the association was
built. The check against `reflection.autosave` happens at call time, not
at define time, so simply modifying the reflection is sufficient.
Fixes#18704
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:
- 9ba21381d7/lib/shoulda/matchers/active_model/allow_value_matcher.rb (L261-L263)
- https://github.com/rails/rails/issues/18653#issuecomment-71197026
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
```
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.
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`.
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.
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
- Fixtures with non-string labels such as integers should be accessed
using integer label as key. For eg. pirates(1) or pirates(42).
- But this results in NotFound error because the label is converted into string before
looking up into the fixtures hash.
- After this commit, the label is converted into string only if its a
symbol.
- This issue was fount out while adding a test case for
https://github.com/rails/rails/commit/7b910917.
Before this change we had a small set of "truthy", and all others
are "falsy".
Now, we have a small set of "falsy" values and all others are
"truthy" matching Ruby's semantics.
Before this change any error raised inside a transaction callback
are rescued and printed in the logs.
Now these errors are not rescue anymore and just bubble up,
as the other callbacks.
This stems from [a comment](rails#17227 (comment)) by @dhh.
In summary:
* New Rails 5.0 apps will not accept `return false` as a way to halt callback chains, and will not display a deprecation warning.
* Existing apps ported to Rails 5.0 will still accept `return false` as a way to halt callback chains, albeit with a deprecation warning.
For this purpose, this commit introduces a Rails configuration option:
```ruby
config.active_support.halt_callback_chains_on_return_false
```
For new Rails 5.0 apps, this option will be set to `false` by a new initializer
`config/initializers/callback_terminator.rb`:
```ruby
Rails.application.config.active_support.halt_callback_chains_on_return_false = false
```
For existing apps ported to Rails 5.0, the initializers above will not exist.
Even running `rake rails:update` will not create this initializer.
Since the default value of `halt_callback_chains_on_return_false` is set to
`true`, these apps will still accept `return true` as a way to halt callback
chains, displaying a deprecation warning.
Developers will be able to switch to the new behavior (and stop the warning)
by manually adding the line above to their `config/application.rb`.
A gist with the suggested release notes to add to Rails 5.0 after this
commit is available at https://gist.github.com/claudiob/614c59409fb7d11f2931
Before this commit, returning `false` in an ActiveRecord `before_` callback
such as `before_create` would halt the callback chain.
After this commit, the behavior is deprecated: will still work until
the next release of Rails but will also display a deprecation warning.
The preferred way to halt a callback chain is to explicitly `throw(:abort)`.
Add setting of FK for throgh associations while building
Conflicts:
activerecord/CHANGELOG.md
activerecord/test/cases/associations/has_many_through_associations_test.rb
Incompatible to rounding behavior between MySQL 5.6 and earlier.
In 5.5, when you insert `2014-08-17 12:30:00.999999` the fractional part
is ignored. In 5.6, it's rounded to `2014-08-17 12:30:01`:
http://bugs.mysql.com/bug.php?id=68760
This error only happens when the foreign key is missing.
Before this fix the following exception was being raised:
NoMethodError: undefined method `val' for #<Arel::Nodes::BindParam:0x007fc64d19c218>
Now the message is:
ActiveRecord::UnknownAttributeError: unknown attribute 'foreign_key' for Model.
When table has a composite primary key, the `primary_key` method for
sqlite3 and postgresql was only returning the first field of the key.
Ensures that it will return nil instead, as AR dont support composite pks.
We only support classes which provide a no-args constructor to use as a
default value. We can provide a more helpful error message if we catch
this when `serialize` is called, rather than letting it error when you
try to assign the attribute.
Fixes#18224
This bug occurs when an attribute of an ActiveRecord model is an
ActiveRecord::Type::Integer type or a ActiveRecord::Type::Decimal type (or any
other type that includes the ActiveRecord::Type::Numeric module. When the value
of the attribute is negative and is set to the same negative value, it is marked
as changed.
Take the following example of a Person model with the integer attribute age:
class Person < ActiveRecord::Base
# age :integer(4)
end
The following will produce the error:
person = Person.new(age: -1)
person.age = -1
person.changes
=> { "age" => [-1, -1] }
person.age_changed?
=> true
The problematic line is here:
module ActiveRecord
module Type
module Numeric
...
def non_numeric_string?(value)
# 'wibble'.to_i will give zero, we want to make sure
# that we aren't marking int zero to string zero as
# changed.
value.to_s !~ /\A\d+\.?\d*\z/
end
end
end
end
The regex match doesn't accept numbers with a leading '-'.
- Right now, there is no method to update multiple records with
validations and callbacks.
- Changed the behavior of existing `update` method so that when `id`
attribute is not given and the method is called on an `Relation`
object, it will execute update for every record of the `Relation` and
will run validations and callbacks for every record.
- Added test case for validating that the callbacks run when `update` is
called on a `Relation`.
- Changed test_create_columns_not_equal_attributes test from
persistence_test to include author_name column on topics table as it
it used in before_update callback.
- This change introduces performance issues when a large number of
records are to be updated because it runs UPDATE query for every
record of the result. The `update_all` method can be used in that case
if callbacks are not required because it will only run single UPDATE
for all the records.
Closes#17945
`db:test:prepare` still purges the database to always keep the test
database in a consistent state.
This patch introduces new problems with `db:schema:load`. Prior
to the introduction of foreign-keys, we could run this file against
a non-empty database. Since every `create_table` containted the
`force: true` option, this would recreate tables when loading the schema.
However with foreign-keys in place, `force: true` wont work anymore and
the task will crash.
/cc @schneems
To be possible to use a custom column name to save/read the polymorphic
associated type in a has_many or has_one polymorphic association, now users
can use the option :foreign_type to inform in what column the associated object
type will be saved.
When running the following migration:
change_table(:table_name) { |t| t/timestamps }
The following error was produced:
wrong number of arguments (2 for 1) .... /connection_adapters/abstract/schema_statements.rb:851:in `remove_timestamps'
This is due to `arguments` containing an empty hash as its second
argument.
This reverts deprecations added in #13528.
The task is brought back for two reasons:
1. Give plugins a way to hook into the test database initialization process
2. Give the user a way to force a test database synchronization
While `test:prepare` is still a dependency of every test task, `db:test:prepare`
no longer hooks into it. This means that `test:prepare` runs before the schema
is synchronized. Plugins, which insert data can now hook into `db:test:prepare`.
The automatic schema maintenance can't detect when a migration is rolled-back,
modified and reapplied. In this case the user has to fall back to `db:test:prepare`
to force the synchronization to happen.
`.reflections` public API changed to return a String instead of a Symbol
as keys.
see commit 1f31488499111fdfce79d8dc1cc8fb008f7cdb25 and 6259e4e2dcca9a79f22f96658c33efe81936bc0d
[fixes#16928]
[fixes#17610]
Prior to this patch you'd end up with an error like:
```
ActiveRecord::RecordNotFound: Couldn't find <Model> with 'id'=<id> [WHERE (<default_scope condition>)]
```
Fix that a collection proxy could be cached before the save of the owner, resulting in an invalid proxy lacking the owner’s id
Conflicts:
activerecord/CHANGELOG.md
In practical terms, this allows serialized columns and tz aware columns
to be used in wheres that go through joins, where they previously would
not behave correctly. Internally, this removes 1/3 of the cases where we
rely on Arel to perform type casting for us.
There were two non-obvious changes required for this. `update_all` on
relation was merging its bind values with arel's in the wrong order.
Additionally, through associations were assuming there would be no bind
parameters in the preloader (presumably because the where would always
be part of a join)
[Melanie Gilman & Sean Griffin]
The MySQLAdapter type map used the lowest priority for enum types.
This was the result of a recent refactoring and lead to some broken lookups
for enums with values that match other types. Like `8bit`.
This patch restores the priority to what we had before the refactoring.
/cc @sgrif
`add_reference` can very helpfully add a multi-column index when you use
it to add a polymorphic reference. However, the first column in the
index is the `id` column, which is less than ideal.
The [PostgreSQL docs][1] say:
> A multicolumn B-tree index can be used with query conditions that
> involve any subset of the index's columns, but the index is most
> efficient when there are constraints on the leading (leftmost)
> columns.
The [MySQL docs][2] say:
> MySQL can use multiple-column indexes for queries that test all the
> columns in the index, or queries that test just the first column, the
> first two columns, the first three columns, and so on. If you specify
> the columns in the right order in the index definition, a single
> composite index can speed up several kinds of queries on the same
> table.
In a polymorphic relationship, the type column is much more likely to be
useful as the first column in an index than the id column. That is, I'm
more likely to query on type without an id than I am to query on id
without a type.
[1]: http://www.postgresql.org/docs/9.3/static/indexes-multicolumn.html
[2]: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
This would be helpful if 2 models have an attribute that has a similar
name to the other. e.g:
before:
User.new(name: "Yuki Nishijima", projects_attributes: [name: "kaminari"])
# => ActiveRecord::UnknownAttributeError: unknown attribute: name
after:
User.new(name: "Yuki Nishijima", projects_attributes: [name: "kaminari"])
# => ActiveRecord::UnknownAttributeError: unknown attribute on User: name
This would be helpful if 2 models have an attribute that has a similar
name to the other. e.g:
before:
User.new(name: "Yuki Nishijima", projects_attributes: [name: "kaminari"])
# => ActiveRecord::UnknownAttributeError: unknown attribute: name
after:
User.new(name: "Yuki Nishijima", projects_attributes: [name: "kaminari"])
# => ActiveRecord::UnknownAttributeError: unknown attribute on User: name
068f092ced8483e557725542dd919ab7c516e567 registered autosave callbacks
as `after_save` callbacks. This caused the regression described in #17209.
Autosave callbacks should be registered as `after_update` and
`after_create` callbacks, just like before.
This is a partial revert of 068f092ced8483e557725542dd919ab7c516e567.
Fixes#17209.
Honoring an overidden `rack.test` allows testing closed connection between
multiple requests. This is useful if you're working on database resiliency, to
ensure the connection is in the expected state from one request to another on
the same worker.
it doesn't work on SQLite3 since it doesn't support truncate, but that's
OK. If you call truncate on the connection, you're now bound to that
database (same as if you use hstore or any other db specific feature).
Allows :limit defaults to be changed without pulling the rug out from
under old migrations that omitted :limit because it matched the default
at the time.
`AbstractAdapter#supports_views?` defaults to `false` so we have to turn it on
in adapter subclasses. Currently the flag only controls test execution.
/cc @yahonda
Closes#16684.
This is achieved by always generating `GeneratedAssociationMethods` when
`ActiveRecord::Base` is subclassed. When some of the included modules
of `ActiveRecord::Base` were reordered this behavior was broken as
`Core#initialize_generated_modules` was no longer called. Meaning that
the module was generated on first access.
[Joshua Cody & Yves Senn]
Closes#16757.
Prior to this patch schema loading rake tasks had the potential to leak a
connection to a different database. This had side-effects when rake tasks
operating on the current connection (like `db:seed`) were chained.
Sets the connection collation to the database collation configured
in database.yml. Otherwise, `SET NAMES utf8mb4` will use the default
collation for that charset (utf8mb4_general_ci) when you may have chosen
a different collation, like utf8mb4_unicode_ci.
This only applies to literal string comparisons, not column values, so
it is unlikely to affect you.
This is a reacon to d6c1205584 (commitcomment-7502487)
This backwards incompatibility was introduced with d6c12055 to fix#7516.
However both `connection.default_sequence_name` and `model.sequence_name` are public API.
The PostgreSQL adapter should honor the interface and return strings.
/cc @matthewd @chancancode
with dynamic conditions.
Fixes#16128
This bug was introduced in c35e438620
so it's present from 4.1.2-rc1 and after.
c35e438620
merges any relation scopes passed as proc objects to the relation,
but does *not* take into account the arity of the lambda.
To reproduce: https://gist.github.com/Agis-/5f1f0d664d2cd08dfb9b
Currently, Active Record will rescue any errors raised within
after_rollback/after_create callbacks and print them to the
logs. Next versions of rails will not rescue those errors anymore,
and just bubble them up, as the other callbacks.
This adds a opt-in flag to enable that behaviour, of not rescuing
the errors.
Example:
# For not swallow errors in after_commit/after_rollback
config.active_record.errors_in_transactional_callbacks = true
[fixes#13460]
after_commit should not run in nested transactions, however they should
run once the outermost transaction gets committed. This patch fixes the
problem copying the records from the Savepoint to its parent. So the
RealTransaction will have all records that needs to run callbacks on it.
[fixes#16425]
[Yves Senn & Matthew Draper]
The column check was embodied in the defaul index name.
If the :name option was used, the specified columns were not verified at all.
Given:
```
assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_yo_momma)
```
That index could have been defined on any field, not necessarily on `:foo_id`.
Fixed an issue where custom accessor methods (such as those generated by
`enum`) with the same name as a global method are incorrectly overridden
when subclassing.
This was partially fixed in 4155431 then broken again by e5f15a8.
Fixes#16288.
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
The rake tasks and the `DatabaseTakss` adapter classes used to
assume a configuration at some places. This forced the rake
tasks to establish a specific connection before calling into
`load_schema`.
After #15394 this started to cause issues because it could
`purge` the wrong database before loading the schema.
`source_macro` is no longer used in any ActiveRecord code. I've
chosen to deprecate it because it was not marked as nodoc and may
be in use outside of rails source.
Previously this method always established a connection to the test database.
This resulted in buggy behavior when combined with other tasks like
`bin/rake db:schema:load`.
This was one of the reasons why #15394 (22e9a91189af2c4e6217a888e77f22a23d3247d1)
was reverted:
> I’ve replicated it on a new app by the following commands: 1) rails
generate model post:title, 2) rake db:migrate, 3) rake
db:schema:load, 4) rails runner ‘puts Post.first’. The last command
goes boom. Problem is that rake db:schema:load wipes the database,
and then doesn’t actually restore it. This is all on MySQL. There’s
no problem with SQLite.
-- DHH
22e9a91189 (commitcomment-6834245)