Commit Graph

19387 Commits

Author SHA1 Message Date
eileencodes
1d03262131
Force connected_to to load the records if it's a Relation
Fixes #38332

If the `connected_to` block returns a relation and does not inspect, or
load that relation before returning it, the block will exit before the
database is queried. This causes the wrong database connection to be
queried.

The consequences of this are getting records from the primary instead of
the replica, and potentially having database performance impact.

Relations lazily query the database. If you return the relation from the
block like:

```
posts = ActiveRecord::Base.connected_to(role: :reading) { Post.where(id: 1) }
```

`posts.first` will be queried from the `writing` connection instead
because it's lazy and performed outside the block. Any query that loads
the relation (ie `to_a`) inside the block would eagerly load the
relation's records and not exhibit this bug.

`connected_to` now checks if the return value is a `Relation` and if so
calls `load`.

Co-authored-by: Aaron Patterson <aaron.patterson@gmail.com>
2020-01-28 13:25:19 -05:00
Larry Reid
2d552925e2 Regexp escape table name for MS SQL 2020-01-28 08:08:04 -08:00
Ryuta Kamizono
95bd55eca3
Merge pull request #38319 from kamipo/make_default_scoped_public
Expose `klass.default_scoped` as public API
2020-01-28 05:53:13 +09:00
Ryuta Kamizono
15426be1a1 Avoid making query when using where(attr: out-of-range-value)
Like as before Rails 6.0.

Closes #38309.
2020-01-27 14:26:26 +09:00
Ryuta Kamizono
0d0c30e534 Avoid making query when using where(attr: []) for pluck
Follow up #37266.
2020-01-27 13:59:34 +09:00
Ryuta Kamizono
dc06d4bfb0 current_scope{,=} are public methods
`send` is not necessary.
2020-01-27 10:30:47 +09:00
Ryuta Kamizono
7cc96c9a9d Expose klass.default_scoped as public API
`default_scoped` is an only way to enforce returning a scope with
default scopes in a scoping, and it is needed for migration to avoid
leaking scope (#35280, #37727).

Closes #38241.
2020-01-27 10:01:05 +09:00
Rafael França
f78fb42b51
Merge pull request #38298 from tjschuck/update_all_document_return_value
Document the return value of update_all [ci skip]
2020-01-23 18:27:46 -05:00
Rafael França
624cbd7c43
Merge pull request #37488 from dylanahsmith/model-adapter-type-lookup
Use the model's adapter for the attribute type lookup
2020-01-23 18:05:49 -05:00
T.J. Schuck
b488d8e089 Document the return value of update_all [ci skip] 2020-01-23 16:16:01 -05:00
Carlos Antonio da Silva
2d7ff70b3f Fix Active Record changelog [ci skip]
Follow-up of 1ee4a8812fcaf2de48e5ab65d7f707c391fce31d.
2020-01-23 17:23:47 -03:00
eileencodes
1ee4a8812f
Move advisory lock to it's own connection
This PR moves advisory lock to it's own connection instead of
`ActiveRecord::Base` to fix #37748. As a note the issue is present on
both mysql and postgres. We don't see it on sqlite3 because sqlite3
doesn't support advisory locks.

The underlying problem only appears if:

1) the app is using multiple databases, and therefore establishing a new
connetion in the abstract models
2) the app has a migration that loads a model (ex `Post.update_all`)
which causes that new connection to get established.

This is because when Rails runs migrations the default connections are
established, the lock is taken out on the `ActiveRecord::Base`
connection. When the migration that calls a model is loaded, a new
connection will be established and the lock will automatically be
released.

When Rails goes to release the lock in the ensure block it will find
that the connection has been closed. Even if the connection wasn't
closed the lock would no longer exist on that connection.

We originally considered checking if the connection was active, but
ultimately that would hide that the advisory locks weren't working
correctly because there'd be no lock to release.

We also considered making the lock more granular - that it only blocked
on each migration individually instead of all the migrations for that
connection. This might be the right move going forward, but right now
multi-db migrations that load models are very broken in Rails 6.0 and
master.

John and I don't love this fix, it requires a bit too much knowledge of
internals and how Rails picks up connections. However, it does fix the
issue, makes the lock more global, and makes the lock more resilient to
changing connections.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-23 14:36:32 -05:00
Eileen M. Uchitelle
b0d4413ae7
Merge pull request #38247 from rosa/save-context-with-response
Allow updating the database selector context with the response and not only the request
2020-01-23 13:54:00 -05:00
Katrina Owen
2c2ff8228e
Allow schema cache path to be defined in the config file
This updates the database tasks for dumping the Active Record schema cache as
well as clearing the schema cache file, allowing the path to be defined in the
database configuration YAML file.

As before, the value can also be defined in an ENV variable, though this would
not work for a multi-db application. If the value is specified neither in the
DB config, nor in the ENV, then the path will continue to be derived from the
DB config spec_name.

Note that in order to make this change cleaner I also moved a bit of logic
out of a rake task and into the DatabaseTasks class, for symmetry.

We have two rake tasks for the schema cache:

    $ rake db:schema:cache:dump
    $ rake db:schema:cache:clear

The cache:dump task was implemented in DatabaseTasks, but the
cache:clear one was not.

I also added some tests for the behavior that I was changing, since some of
the code paths weren't tested.
2020-01-23 08:18:23 -07:00
eileencodes
7315c91d45
Deprecate #remove_connection in favor of #remove_connection_pool
Calling `#remove_connection` on the handler is deprecated in favor of
`#remove_connection_pool`. This change was made to support changing the
return value from a hash to a `DatabaseConfig` object.
`#remove_connection` will be removed in 6.2.

NOTE: `#remove_connection` on `ActiveRecord::Base` will also now return
a `DatabaseConfig` object. We didn't use a deprecation here since
it's not documented that this method used to return a `Hash`.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-21 16:49:20 -05:00
Ryuta Kamizono
0dad1e3e77 *_for_alter methods should also takes keyword arguments
Follow up 5572df92be8c529909277ee8e4ac5b9da26b893a.
2020-01-20 09:15:29 +09:00
Ryuta Kamizono
5572df92be Invertable methods should have compatible method signature
Otherwise it is hard to invert non-kwargs method to kwargs method.

This makes table and column options to be synchronized as kwargs.
2020-01-20 06:57:16 +09:00
Ryuta Kamizono
01e248b4d0 add_foreign_key's arguments are compatible (invertable) for remove_foreign_key without customize
So the custom `invert_add_foreign_key` is a little redundant.
2020-01-20 05:33:24 +09:00
Ryuta Kamizono
7fa1f4014b Fix typo 2020-01-20 01:35:12 +09:00
eileencodes
2a53fe638d
Deprecate and replace #default_hash and #[]
Database configurations are now objects almost everywhere, so we don't
need to fake access to a hash with `#default_hash` or it's alias `#[]`.
Applications should `configs_for` and pass `env_name` and `spec_name` to
get the database config object. If you're looking for the default for
the test environment you can pass `configs_for(env_name: "test", spec_name:
"primary")`. Change test to developement to get the dev config, etc.

`#default_hash` and `#[]` will be removed in 6.2.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-17 16:08:12 -05:00
Dylan Thacker-Smith
3b600a3fb6 Use the model's adapter for the attribute type lookup 2020-01-16 21:26:08 -05:00
Rosa Gutierrez
62e05ce96f Allow updating the database selector context with the response
Currently the database selector middleware only passes the request to
the context.

This is enough for the resolver to decide whether to switch
to the primary, but for a custom resolver and a custom context class,
it's not enough to persist any information for subsequent requests. For
example, say you want to use a cookie to decide whether when to switch.
It's not possible to set the response cookie from this middleware, since
neither the context nor the resolver have access to it.

This includes an extra step to update the context after the response has
been computed.
2020-01-16 19:25:22 +01:00
Ryuta Kamizono
c699cbc4fe Remove SQLite version support caveats [ci skip]
Follow up #36255.
2020-01-16 07:14:54 +09:00
Ryuta Kamizono
6607618afd If dependent: nil is valid for has_many, it also be valid for has_one
Follow up #35504.

[ci skip]
2020-01-16 07:05:20 +09:00
Ryuta Kamizono
c900cdfdc3 Avoid extra Array allocation 2020-01-16 07:00:51 +09:00
Ryuta Kamizono
36e6a51662 Fix CI failures due to MySQL 8.0.19 no longer output integer display width unless ZEROFILL is also used
https://buildkite.com/rails/rails/builds/66475#7a6c54bc-4ed3-4676-b196-4fee031f43bf

Fixes #38226.
2020-01-15 21:40:10 +09:00
Douglas Lara
10803d6985 fix typos 2020-01-15 00:11:40 -03:00
Carlos Antonio da Silva
10a37f33b7 Fix my own typo now, ops! [ci skip] 2020-01-14 09:27:28 -03:00
Carlos Antonio da Silva
d277e871e9 Fix typo and make indent/examples consistent on docs for where.missing
[ci skip]
2020-01-14 09:19:29 -03:00
Prem Sichanugrist
0ac7b8c843 Remove an empty line from generated migration
Currently, if you run `rails g migration remove_column_from_models`,
there is an empty line before `remove_column` line because we forgot to
use `-%>` in the template:

    $ bin/rails g migration remove_title_from_posts title:string
          invoke  active_record
          create    db/migrate/20200114061235_remove_title_from_posts.rb

    $ cat db/migrate/20200114061235_remove_title_from_posts.rb
    class RemoveTitleFromPosts < ActiveRecord::Migration[6.1]
      def change

        remove_column :posts, :title, :string
      end
    end

This commit adds the missing `-` in front of `-%>` to make it removes
the empty line.
2020-01-14 15:22:45 +09:00
Ryuta Kamizono
164069fd2d Fix random CI failure due to non-deterministic sorting order
https://buildkite.com/rails/rails/builds/66424#a1fdb92a-a9a0-4ff2-afc8-a59410cd4fdf/1016-1027
2020-01-14 08:44:05 +09:00
Gannon McGibbon
f72f743dc3 Add scale support to ActiveRecord::Validations::NumericalityValidator 2020-01-13 11:00:22 -05:00
Tom Rossi
9bfe89e68e Introducing the where.missing query method. 2020-01-11 09:14:25 -05:00
Edouard CHIN
6488f52b83 Fix NumericalityValidator when precision is too high:
- When a column with a precision that is higher than what the system
  allows, it would result in an error:

  ```sh
    require "bigdecimal/util"

    123.4.to_d(20) => ArgumentError, precision is too high
  ```

  To fix that problem we need to check what the max number of digits
  a Float is allowed to have, we can achieve that with `BigDecimal.double_fig`

  Fix #38209
2020-01-10 13:31:27 -04:00
Eileen M. Uchitelle
2c07d162b3
Merge pull request #38204 from eileencodes/fix-reading-conn-so-text-fixtures-raise-when-writing-on-replica
Ensure the reading connection always raises if we try to write
2020-01-10 11:15:25 -05:00
Rafael França
89a7219db8
Merge pull request #38193 from Edouard-chin/ec-fix-numericality-on-abstract-class
Fix numericality validator when defined on abstract class:
2020-01-10 11:12:27 -05:00
Edouard CHIN
c507e9302a Fix numericality validator when defined on abstract class:
- ### Problem

  It's no longer possible to define a numeric validation on abstract
  class:

  ```ruby
    class AnimalsBase < ApplicationRecord
      self.abstract_class = true

      validates :age, numericality: { min: 18 }
    end

    class Dog < AnimalsBase
    end

    Dog.create!(age: 0) => ActiveRecord::TableNotSpecified: Dog has no table configured. Set one with Dog.table_name=
  ```

  ### Solution

  Instead of trying to get the type for attribute on the class
  defining the validation, get it from the record being validated.
2020-01-10 10:35:54 -04:00
eileencodes
1c98e6c005
Ensure the reading connection always raises if we try to write
Since test fixtures share connections (due to transactional tests) we
end up overwriting the reading configuration so Rails doesn't recognize
it as a replica connection.

This change ensures that if we're using the `reading` role that
connections will always have prevent writes turned on.

If you need a replica connection that does not block writes, you should
use a different role name other than `:reading`.

The db selector test and connection handlers test have been updated to
test for these changes. In the db selector test we don't always have a
writing handler so I updated test fixtures to return if that's nil.

Lastly one test needed to be updated to use a different handler name due
to it needing to write to successfully test what it needs to test.

Fixes #37765
2020-01-09 18:34:28 -05:00
eileencodes
d89ee16bbc
Fix the reading can write resolver test
This test wasn't correct. If we're calling `resolver.read` and want to
actually read from the replicas then the role would be reading not
writing. This was because the session store needed to be changed so that
we actually are "reading from the replicas" instead of reading from the
primary.
2020-01-09 16:45:01 -05:00
eileencodes
b74fbe4e51
Deprecate "primary" as a connection_specification_name for ActiveRecord::Base
As multiple databases have evolved it's becoming more and more
confusing that we have a `connection_specification_name` that defaults
to "primary" and a `spec_name` on the database objects that defaults to
"primary" (my bad).

Even more confusing is that we use the class name for all
non-ActiveRecord::Base abstract classes that establish connections. For
example connections established on `class MyOtherDatabaseModel <
ApplicationRecord` will use `"MyOtherDatabaseModel"` as it's connection
specification name while `ActiveRecord::Base` uses `"primary"`.

This PR deprecates the use of the name `"primary"` as the
`connection_specification_name` for `ActiveRecord::Base` in favor of
using `"ActiveRecord::Base"`.

In this PR the following is true:

* If `handler.establish_connection(:primary)` is called, `"primary"`
will not throw a deprecation warning and can still be used for the
`connection_specification_name`. This also fixes a bug where using this
method to establish a connection could accidentally overwrite the actual
`ActiveRecord::Base` connection IF that connection was not using a
configuration named `:primary`.
* Calling `handler.retrieve_connection "primary"` when
`handler.establish_connection :primary` has never been called will
return the connection for `ActiveRecord::Base` and throw a deprecation
warning.
* Calling `handler.remove_connection "primary"` when
`handler.establish_connection :primary` has never been called will
remove the connection for `ActiveRecord::Base` and throw a deprecation
warning.

See #38179 for details on more motivations for this change.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-08 16:49:41 -05:00
Rafael França
2c7553cd31
Merge pull request #38118 from mkrfowler/reduce_preloaded_records
Reduce the number of records loaded when preloading across a `has_one`
2020-01-08 11:45:53 -03:00
Eileen M. Uchitelle
09fbee82dc
Merge pull request #38179 from eileencodes/fix-resolve-symbol-conn
Restore previous behavior of parallel test databases
2020-01-07 16:59:02 -05:00
eileencodes
c05098852c
Restore previous behavior of parallel test databases
This commit is somewhat of a bandaid fix for a bug that was revealed in #38029
and then #38151. #38151 can cause problems in certain cases when an app has
a 3-tier config, with replicas, because it reorders the configuration
and changes the implict default connection that gets picked up.

If an app calls `establish_connection` with no arguments or doesn't call
`connects_to` in `ApplicationRecord` AND uses parallel testing
databases, the application may pick up the wrong configuration.

This is because when the code in #38151 loops through the configurations
it will update the non-replica configurations and then put them at the
end of the list. If you don't specify which connection you want, Rails
will pick up the _first_ connection for that environment. So given the
following configuration:

```
test:
  primary:
    database: my_db
  replica:
    database: my_db
    replica: true
```

The database configurations will get reordered to be `replica`,
`primary` and when Rails calls `establish_connection` with no arguments
it will pick up `replica` because it's first in the list.

Looking at this bug it shows that calling `establish_connection` with no
arguments (which will pick up the default env + first configuration in
the list) OR when `establish_connection` is called with an environment
like `:test` it will also pick up that env's first configuration. This
can have surprising behavior in a couple cases:

1) In the parallel testing changes we saw users getting the wrong db
configuration and hitting an `ActiveRecord::ReadOnlyError`
2) Writing a configuration that puts `replica` before `primary`, also
resulting in a `ActiveRecord::ReadOnlyError`

The real fix for this issue is to deprecate calling
`establish_connection` with an env or nothing and require an explcit
configuration (like `primary`). This would also involve blessing
`:primary` as the default connection Rails looks for on boot. In
addition, this would require us deprecating connection specification
name "primary" in favor of the class name always since that will get
mega-confusing (seriously, it's already mega-confusing).

We'll work on fixing these underlying issues, but wanted to get a fix
out that restores previous behavior.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-07 16:03:00 -05:00
Michael Fowler
989dda36d6 Fuse traversals of the record set when preloading
Although consuming code will almost certainly retraverse this set, we can avoid
walking it twice here. As an extra upside, we can avoid the double-use of an
identity-sensitive hash; this is convenient, because it is another collection we
actually don't need to build.
2020-01-08 08:14:04 +13:00
Michael Fowler
9aa59f9d4a Avoid extraneous preloading when loading across has_one associations
The Preloader relies on other objects to bind the retrieved records to their
parents. When executed across a hash, it assumes that the results of
`preloaded_records` is the appropriate set of records to pass in to the next
layer.

Filtering based on the reflection properties in `preloaded_records` allows us to
avoid excessive preloading in the instance where we are loading across a
`has_one` association distinguished by an order (e.g. "last comment" or
similar), by dropping these records before they are returned to the
Preloader. In this situation, we avoid potentially very long key lists in
generated queries and the consequential AR object instantiations.

This is mostly relevant if the underlying linked set has relatively many
records, because this is effectively a multiplier on the number of records
returned on the far side of the preload. Unfortunately, avoiding the
over-retrieval of the `has_one` association seems to require substantial changes
to the preloader design, and probably adaptor-specific logic -- it is a
top-by-group problem.
2020-01-08 08:14:04 +13:00
Rafael França
7085b5467e
Merge pull request #38131 from kddeisz/nulls
Allow #nulls_first and #nulls_last in PostgreSQL
2020-01-07 11:47:46 -03:00
Stuart
b16360cfb6 Move nil? check to open_ended? method 2020-01-06 22:06:14 -05:00
Gannon McGibbon
f337669b0b
Merge pull request #36664 from gmcgibbon/add_ar_numericality_validation
Add ActiveRecord::Validations::NumericalityValidator
2020-01-06 19:23:23 -05:00
Gannon McGibbon
b5c9974fa7 Add ActiveRecord::Validations::NumericalityValidator
Add Active Record numericality validator with support for casting
floats using a database columns' precision value.
2020-01-06 19:01:29 -05:00
Rafael França
00b277bda0
Merge pull request #38166 from jules2689/master
Only assign @new_record_before_save once in autosave_association
2020-01-06 18:56:43 -03:00
Julian Nadeau
d93f1ab48c
Remove comment 2020-01-06 16:18:32 -05:00
Julian Nadeau
901d62c586
Only assign @new_record_before_save once in autosave_association
If we defined a callback before an association that updates the object, then this may end up being
manipulated to being `false` when it should be `true`. We guard this be only defining it once.

The implication of it being false, in this case, is that the children aren't updated with the parent_id
and so they fail to associate to one another.

See https://github.com/rails/rails/issues/38120 for more details
2020-01-06 12:57:33 -05:00
Simon Perepelitsa
b91dd419e2 Update tests 2020-01-06 20:43:20 +03:00
Simon Perepelitsa
7ac351aaca Use full option names in psql / pg_dump for clarity 2020-01-06 19:46:42 +03:00
Eileen M. Uchitelle
be40e8e5af
Merge pull request #38099 from alipman88/avoid_unecessary_query_if_cache_versioning_enabled
Avoid unnecessary SQL query when calling ActiveRecord::Relation#cache_key
2020-01-06 08:52:41 -05:00
Rafael França
f619ac91d3
Merge pull request #37299 from kobsy/specify-pk-as-conflict-target
Include primary key in insert_all conflict target if specified
2020-01-05 10:09:48 -03:00
Mike Vastola
3806d073bf Fix adding non-null column to existing SQLite3 table
Forces adding the column by way of copying the table due to lack of
support in SQLite3 adapter.

Fixes #38129
2020-01-04 11:05:01 -05:00
Ryuta Kamizono
5a010d8537 Merge pull request #38145 from sinsoku/avoid_assigning_the_same_value_to_join_values
Avoid assigning duplicate values to join_values
2020-01-04 21:31:36 +09:00
sinsoku
8d58bdda20
Allow or in case of from clause with same value 2020-01-04 20:32:51 +09:00
sinsoku
aca85f6259
Avoid assigning duplicate values in QueryMethods
The ArgumentError occurs even though structures is compatible.
Because some query methods keep duplicate values.

For example, the behavior of `joins` method is as following:

```ruby
relation = Post.joins(:author).joins(:author)
relation.joins_values
#=> [:author, :author]
relation.or(Post.joins(:author))
#=> ArgumentError: Relation passed to #or must be structurally compatible. Incompatible values: [:joins]
```

This commit changes to not keep duplicate values.

Fixes #38052
2020-01-04 20:32:33 +09:00
John Crepezzi
1f938f5265 Pass env_name as a string in test databases
In 154abca we switched from using `Rails.env` to fetch the `env_name` to
`ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_sym` which
changed the type from a `String` to a `Symbol`.

This commit brings things back to the original state, so we can find the
configurations correctly!

It also modifies the configuration in the configurations array, so that
future connections can find the database with the updated keyword value.
2020-01-03 17:07:25 -05:00
Ryuta Kamizono
1414910502 Fix test failure if prepared_statements is flipped 2020-01-03 18:51:15 +09:00
Aaron Lipman
58b040964f Enforce fresh ETag header after collection changes
Add ActiveRecord::Relation#cache_key_with_version. This method will be
used by ActionController::ConditionalGet to ensure that when collection
cache versioning is enabled, requests using ConditionalGet don't return
the same ETag header after a collection is modified.

Prior to the introduction of collection cache versioning in
4f2ac80d4cdb01c4d3c1765637bed76cc91c1e35, all collection cache keys
included a version. However, with cache versioning enabled, collection
cache keys remain constant. In turn, ETag headers remain constant,
rendering them ineffective.

This commit takes the cache_key_with_version method used for individual
Active Record objects (from aa8749eb52d7919a438940c9218cad98d892f9ad),
and adds it to collections.
2020-01-02 21:09:53 -05:00
Rafael França
122e4791b0
Merge pull request #38133 from onk/insert_all_sql
Separate with space between table name and columns list in SQL of insert_all
2020-01-02 20:02:58 -03:00
Takafumi ONAKA
fc1261256d Separate with space between table name and columns list in SQL of insert_all
In arel, there is a space between the table name and columns list when INSERT.
3c28e79b61/activerecord/lib/arel/visitors/to_sql.rb (L56)

```ruby
User.create!(name: "foo")
# INSERT INTO `users` (`name`) VALUES ('foo')
              ^^^^^^^^^^^^^^^^
```

But SQL of insert_all is not separated.

```ruby
User.insert_all!([{name: "foo"}])
# INSERT INTO `users`(`name`) VALUES ('foo')
              ^^^^^^^^^^^^^^^
```

This is not a problem (because it is correct as SQL), but fixing this will make unified behavior.

A known issue is that database_rewinder fails to parse table name on insert_all.
https://github.com/amatsuda/database_rewinder/blob/v0.9.1/lib/database_rewinder.rb#L51-L54

```ruby
statement = "INSERT INTO `users`(`name`) VALUES ('foo')"
match = statement.match(/\A\s*INSERT(?:\s+IGNORE)?(?:\s+INTO)?\s+(?:\.*[`"]?([^.\s`"]+)[`"]?)*/i)
# => #<MatchData "INSERT INTO `users`(`name`)" 1:")">
# Expected behavior is
# => #<MatchData "INSERT INTO `users`" 1:"users">
```
2020-01-02 17:26:38 +09:00
Abhay Nikam
d8beb77252 Bump license years from 2019 to 2020 [ci skip] 2020-01-01 15:10:31 +05:30
Kevin Deisz
66b19b5dec
Allow #nulls_first and #nulls_last in PostgreSQL
When using PostgreSQL, it's useful to be able to specify NULLS FIRST and NULLS LAST on ordered columns. With this commit you can do that now, as in:

```ruby
User.arel_table[:first_name].desc.nulls_last
```
2019-12-31 15:59:59 -05:00
Carlos Antonio da Silva
8d89e3d180 Fix a couple typos and simplify Active Record changelog entry [ci skip] 2019-12-31 09:15:16 -03:00
Rafael França
4fbb393b25
Merge pull request #35023 from hahmed/deprecate-global-rails-command-docs
Remove reference to global rails command in the docs
2019-12-27 16:39:55 -03:00
Haroon Ahmed
db1ae8cbb4 remove reference to global rails command and replace with bin/rails 2019-12-27 19:32:37 +00:00
Rafael França
fe097fa629
Merge pull request #38086 from yhirano55/activerecord/allow_enum_definitions_with_boolean_values
Allow AR::Enum definitions with boolean values
2019-12-27 12:40:07 -03:00
Yoshiyuki Hirano
f5ec524624 Add test case about assigning nil in enum
This commit will be squished into f4fbdb1b4e after maintainer's review.
2019-12-27 13:58:54 +09:00
Eugene Kenny
d3060af7f5 Clear callback triggers when transaction completes
The `_trigger_update_callback` and `_trigger_destroy_callback`
attributes were added in 9252da96597fbffe2246704556524c4804239552 to
avoid running transactional callbacks when an attempt to modify a record
fails inside a transaction due to the record being invalid, for example.

However the values weren't being reset between transactions, which meant
they leaked from one transaction to another and caused false positives
where unsuccessful modifications still triggered callbacks. Clearing
them when a transaction commits or is rolled back fixes the problem.
2019-12-27 01:33:22 +00:00
Aaron Lipman
76bb9712f2 Avoid unnecessary SQL query when calling cache_key
With collection_cache_versioning enabled, a collection's volatile info
(size & max updated_at timestamp) is included in
ActiveRecord::Relation#cache_version, not #cache_key.

Avoid the SQL query to used determine this volatile info when generating
an un-versioned cache key. This query does not need to be executed
unless cache_version is called separately.
2019-12-26 13:08:59 -05:00
Yoshiyuki Hirano
f4fbdb1b4e Allow AR::Enum definitions with boolean values
If `AR::Enum` is used for boolean field, it would be not expected
behavior for us.

fixes #38075

Problem:

In case of using boolean for enum, we can set with string (hash key)
to instance, but we cannot set with actual value (hash value).

```ruby
class Post < ActiveRecord::Base
  enum status: { enabled: true, disabled: false }
end

post.status = 'enabled'
post.status # 'enabled'

post.status = true
post.status # 'enabled'

post.status = 'disabled'
post.status # 'disabled'

post.status = false
post.status # nil (This is not expected behavior)
```

After looking into `AR::Enum::EnumType#cast`, I found that `blank?`
method converts from false value to nil (it seems it may not intentional behavior).

In this patch, I improved that if it defines enum with boolean,
it returns reasonable behavior.
2019-12-24 07:05:42 -10:00
Ryuta Kamizono
0b3c710d35 tweaks tests 2019-12-23 22:42:54 +09:00
Ryuta Kamizono
c509150136 Merge pull request #37991 from UlrichThomasGabor/patch-1
Regex did not match CREATE TABLE in all cases
2019-12-23 22:40:09 +09:00
Ulrich Thomas Gabor
5220c6e4af Regex did not match CREATE TABLE in all cases
The regular expression did not match CREATE TABLE statements printed out by AWS Aurora MySQL 5.6 instances, because they lack the required space at that position.
2019-12-23 12:33:04 +01:00
Brian Buchalter
53e9438ef2 Ignore test env in DatabaseTasks when DATABASE_URL is present
Fixes https://github.com/rails/rails/issues/28827.

The steps to reproduce are as follows:

git clone git@github.com:bbuchalter/rails-issue-28827.git
cd rails-issue-28827
bundle install
bin/rails db:create

Observe that we create two databases when invoking db:create: development and test. Now observe what happens when we invoke our drop command while using DATABASE_URL.

DATABASE_URL=sqlite3://$(pwd)/db/database_url.sqlite3 bin/rails db:create

As expected, the development environment now uses the DATABASE_URL. What is unexpected is that the test environment does not.

It's unclear what the expected behavior should be in this case, but the cause of it is this: 9f2c74eda0/activerecord/lib/active_record/tasks/database_tasks.rb (L494)

Because of each_local_configuration, there seems to be no way invoke these database rake on only the development environment to ensure DATABASE_URL is respected.

The smallest scope of change I can think to make would be to conditionalize this behavior so it does not get applied when DATABASE_URL is present.
2019-12-20 14:22:31 -08:00
Ryuta Kamizono
ce5718aeef ruby2_keywords for adapters/mysql2/active_schema_test.rb 2019-12-21 03:14:35 +09:00
Mariano Vallés
5665806cc5 Remove extra the in preloader docs 2019-12-20 17:02:49 +01:00
Eileen M. Uchitelle
8ddf0c490f
Merge pull request #38042 from eileencodes/update-read-query
Refactor READ_QUERY and fix missing arguments
2019-12-20 08:41:57 -05:00
Ryuta Kamizono
57ace94c42 Merge pull request #38038 from Shopify/activerecord-ruby-2.7-warnings-6-0-stable-batch-2
Activerecord ruby 2.7 warnings 6 0 stable batch 2
2019-12-20 19:43:49 +09:00
eileencodes
112977cbed Support cursors on readonly queries
This adds `:declare`, `:fetch`, `:move`, and `:close` to allowed queries
when `while_preventing_writes` is set. I didn't support `:open` because
AFAICT `:declar` implcitly opens a cursor and all of my attempts to
write `@connection.execute("OPEN cur_ex")` threw a syntax error on
`OPEN`. It seems like open isn't supported with the client.

Fixes: #37960
2019-12-19 15:43:23 -05:00
eileencodes
9537dfe18d Consolidate code for READ_QUERY
`:begin, :commit, :explain, :release, :rollback, :savepoint, :select,
:with` are used by all the adapters. This commit adds a new constant
called `DEFAULT_READ_QUERY` so that we have somewhere to put the
queries used by all the adapters. Then we can set adapter specific query
parts in those adapters.

I also alphabetized these.
2019-12-19 14:07:56 -05:00
Deividas J
a960f93971 Added: USE sql statement to the READ_QUERY list for mysql 2019-12-19 13:46:42 -05:00
eileencodes
3a6770fb51 Add CHANGELOG for #38029 2019-12-19 12:25:39 -05:00
Eileen M. Uchitelle
2bcf145497
Merge pull request #38029 from seejohnrun/freeze-configuration_hash
Don't allow mutations on configuration_hash
2019-12-19 12:14:42 -05:00
Jean Boussier
9536bc457e Fix Active Record attribute filtering test on Ruby 2.7 2019-12-19 16:16:13 +01:00
eileencodes
154abcab6e Don't allow mutations on configuration_hash
We want to introduce an object-based DSL for building and modifying
configuration objects. As part of that we want to make sure that users
don't think they can modify configuration_hash values and have them
change the configuration. For that reason we're going to freeze the
Hash here, and have modified places in tests where we were modifying
these hashes.

The commit here also adds a test for the Test Databases and in that work
we found that we were calling `Rails.env` and Active Record doesn't load
Rails.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2019-12-19 09:15:24 -05:00
eileencodes
334450bdb0 Update tests to assert something
These tests weren't calling assert, so if the execute didn't raise but
also didn't return anything it would be a broken test that never fails.
We need to always add an assertion so we know what the expected behavior
is.
2019-12-18 10:49:01 -05:00
Rafael França
e4cbf4ed92
Merge pull request #25512 from MOZGIII/patch-1
Ensure result is cleared at ConnectionAdapters::PostgreSQLAdapter#execute_and_clear
2019-12-18 12:38:37 -03:00
Ryuta Kamizono
5d00eb41ca
Merge pull request #38013 from kamipo/remove_connection_id
Remove `:connection_id` in an internal instrument
2019-12-18 18:29:36 +09:00
Ryuta Kamizono
72af0bbc3d Fix typos 2019-12-18 16:47:18 +09:00
Ryuta Kamizono
ed33d869e8 Remove :connection_id in an internal instrument
Related #36456.

I grepped the code base by `git grep -n 'connection_id: '` then I found
extra `connection_id: object_id` which is added at #20818 but unused.

Actually the `connection_id: object_id` is not a connection's object_id
but a connection_handler's object_id, it is very confusing.

Since the `:connection_id` in an internal instrument is not used, we can
just remove the incorrect information.
2019-12-18 16:24:39 +09:00
Rafael Mendonça França
d140ab073f
Remove connection_id key from the sql.active_record notification 2019-12-17 21:16:41 -03:00
Rafael Mendonça França
3869660608
Merge pull request #36456 from rails/remove-object-id
Remove call to object_id
2019-12-17 21:11:28 -03:00
Rafael Mendonça França
47346253ec
Merge pull request #36240 from vishaltelangre/explicity-rollback-behavior-in-nested-transactions
Update documentation to explain the behavior of explicitly raising ActiveRecord::Rollback in a nested transaction [skip ci]
2019-12-17 20:56:16 -03:00
Rafael França
2d56483030
Merge pull request #36589 from yskkin/reversible_remove_columns
Reversible remove_columns
2019-12-17 20:41:25 -03:00
John Crepezzi
b76659e139 Move name key on configuration hash into DatabaseConfig
`name` is used by Rails to find the configuration by connection
specification name, but database adapters don't need to use `name` in
order to establish a connection. This is part of our work to separate
what the database needs to connect (the configuration hash) and the
what Rails needs to find connections (everything else).

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2019-12-17 15:59:49 -05:00