| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While the three-tier config makes it easier to define databases for
multiple database applications, it quickly became clear to offer full
support for multiple databases we need to change the way the connections
hash was handled.
A three-tier config means that when Rails needed to choose a default
configuration (in the case a user doesn't ask for a specific
configuration) it wasn't clear to Rails which the default was. I
[bandaid fixed this so the rake tasks could work](#32271) but that fix
wasn't correct because it actually doubled up the configuration hashes.
Instead of attemping to manipulate the hashes @tenderlove and I decided
that it made more sense if we converted the hashes to objects so we can
easily ask those object questions. In a three tier config like this:
```
development:
primary:
database: "my_primary_db"
animals:
database; "my_animals_db"
```
We end up with an object like this:
```
@configurations=[
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
@env_name="development",@spec_name="primary",
@config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
@env_name="development",@spec_name="animals",
@config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
]>
```
The configurations setter takes the database configuration set by your
application and turns them into an
`ActiveRecord::DatabaseConfigurations` object that has one getter -
`@configurations` which is an array of all the database objects.
The configurations getter returns this object by default since it acts
like a hash in most of the cases we need. For example if you need to
access the default `development` database we can simply request it as we
did before:
```
ActiveRecord::Base.configurations["development"]
```
This will return primary development database configuration hash:
```
{ "database" => "my_primary_db" }
```
Internally all of Active Record has been converted to use the new
objects. I've built this to be backwards compatible but allow for
accessing the hash if needed for a deprecation period. To get the
original hash instead of the object you can either add `to_h` on the
configurations call or pass `legacy: true` to `configurations.
```
ActiveRecord::Base.configurations.to_h
=> { "development => { "database" => "my_primary_db" } }
ActiveRecord::Base.configurations(legacy: true)
=> { "development => { "database" => "my_primary_db" } }
```
The new configurations object allows us to iterate over the Active
Record configurations without losing the known environment or
specification name for that configuration. You can also select all the
configs for an env or env and spec. With this we can always ask
any object what environment it belongs to:
```
db_configs = ActiveRecord::Base.configurations.configurations_for("development")
=> #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800
@configurations=[
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
@env_name="development",@spec_name="primary",
@config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
@env_name="development",@spec_name="animals",
@config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
]>
db_config.env_name
=> "development"
db_config.spec_name
=> "primary"
db_config.config
=> { "adapter"=>"sqlite3", "database"=>"db/development.sqlite3" }
```
The configurations object is more flexible than the configurations hash
and will allow us to build on top of the connection management in order
to add support for primary/replica connections, sharding, and
constructing queries for associations that live in multiple databases.
|
|
|
|
|
|
|
|
| |
`composed_of` is a fairly rare method to call on models. This commit
adds the `Aggregations` module to models that call `composed_of` so that
models that *don't* call `composed_of` don't need to instantiate the
`aggregation_cache` hash. This saves one hash allocation per model
instance that doesn't use `composed_of`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Moves the configs_for and DatabaseConfig struct into it's own file. I
was considering doing this in a future refactoring but our set up forced
me to move it now. You see there are `mattr_accessor`'s on the Core
module that have default settings. For example the `schema_format`
defaults to Ruby. So if I call `configs_for` or any methods in the Core
module it will reset the `schema_format` to `:ruby`. By moving it to
it's own class we can keep the logic contained and avoid this
unfortunate issue.
The second change here does a double loop over the yaml files. Bear with
me...
Our tests dictate that we need to load an environment before our rake
tasks because we could have something in an environment that the
database.yml depends on. There are side-effects to this and I think
there's a deeper bug that needs to be fixed but that's for another
issue. The gist of the problem is when I was creating the dynamic rake
tasks if the yaml that that rake task is calling evaluates code (like
erb) that calls the environment configs the code will blow up because
the environment is not loaded yet.
To avoid this issue we added a new method that simply loads the yaml and
does not evaluate the erb or anything in it. We then use that yaml to
create the task name. Inside the task name we can then call
`load_config` and load the real config to actually call the code
internal to the task. I admit, this is gross, but refactoring can't all
be pretty all the time and I'm working hard with `@tenderlove` to
refactor much more of this code to get to a better place re connection
management and rake tasks.
|
|
|
|
|
|
| |
Skipping over 2.4.0 to sidestep the `"symbol_from_string".to_sym.dup` bug.
References #32028
|
|
|
|
| |
This basically reverts 9d4f79d3d394edb74fa2192e5d9ad7b09ce50c6d
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
callbacks
We pretty frequently get bug reports that "dirty is broken inside of
after callbacks". Intuitively they are correct. You'd expect
`Model.after_save { puts changed? }; model.save` to do the same thing as
`model.save; puts model.changed?`, but it does not.
However, changing this goes much farther than just making the behavior
more intuitive. There are a _ton_ of places inside of AR that can be
drastically simplified with this change. Specifically, autosave
associations, timestamps, touch, counter cache, and just about anything
else in AR that works with callbacks have code to try to avoid "double
save" bugs which we will be able to flat out remove with this change.
We introduce two new sets of methods, both with names that are meant to
be more explicit than dirty. The first set maintains the old behavior,
and their names are meant to center that they are about changes that
occurred during the save that just happened. They are equivalent to
`previous_changes` when called outside of after callbacks, or once the
deprecation cycle moves.
The second set is the new behavior. Their names imply that they are
talking about changes from the database representation. The fact that
this is what we really care about became clear when looking at
`BelongsTo.touch_record` when tests were failing. I'm unsure that this
set of methods should be in the public API. Outside of after callbacks,
they are equivalent to the existing methods on dirty.
Dirty itself is not deprecated, nor are the methods inside of it. They
will only emit the warning when called inside of after callbacks. The
scope of this breakage is pretty large, but the migration path is
simple. Given how much this can improve our codebase, and considering
that it makes our API more intuitive, I think it's worth doing.
|
|\
| |
| | |
Makes touch_later respects no_touching policy
|
| | |
|
|/
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
| |
|
|
|
|
| |
It appears first in `lib/active_record.rb`.
|
|
|
| |
These methods are more expensive than the alternatives, and have strange semantics that are likely undesirable.
|
|
|
|
| |
It was changed by mistake at 428d47adfed8d6aa7b21aec2bf5ad890961c9de3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The focus of this change is to make the API more accessible.
References to method and classes should be linked to make it easy to
navigate around.
This patch makes exzessiv use of `rdoc-ref:` to provide more readable
docs. This makes it possible to document `ActiveRecord::Base#save` even
though the method is within a separate module
`ActiveRecord::Persistence`. The goal here is to bring the API closer to
the actual code that you would write.
This commit only deals with Active Record. The other gems will be
updated accordingly but in different commits. The pass through Active
Record is not completely finished yet. A follow up commit will change
the spots I haven't yet had the time to update.
/cc @fxn
|
| |
|
| |
|
| |
|
|\
| |
| |
| |
| |
| | |
[Doc] Encourage users to user super to override methods.
[ci skip]
|
|/
|
| |
IMO we shouldn't encourage users to use methods they shouldn't need to know about. As Song (in this example) inherits from ActiveRecord, we can use super here instead to get the same effect with the bonus of not knowing how active record actually implements these methods.
|
|
|
|
|
|
|
|
|
|
| |
[fixes #18606]
Make belongs_to use touch over touch_later when running the callbacks.
Add more tests and small method rename
Thanks Jeremy for the feedback.
|
| |
|
| |
|
|
|
|
|
|
| |
Update SecureToken Docs
Add Changelog entry for has_secure_token [ci skip]
|
| |
|
|
|
|
|
| |
value is present. [ci skip]
The way Active Record query methods handle numeric values is a special case, and is not part of Rails's standard definition of present. This update attempts to make this more clear in the docs, so that people don't expect Object#present? to return false if used on a number that is zero.
|
|
|
| |
Update Active Record's attribute query methods documentation to clarify that whether an attribute is present is based on Object#present?. This gives people a place to go see what the exact definition of presence is. [ci skip]
|
|
|
|
| |
full behaviour. [ci skip]
|
| |
|
|
|
|
| |
[ci skip]
|
| |
|
|
|
| |
Documenting a potential source of confusion about how STI classes handle changes.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This refactoring revealed the need for another form of decoration, which
takes a proc to select which it applies to (There's a *lot* of cases
where this form can be used). To avoid duplication, we can re-implement
the old decoration in terms of the proc-based decoration.
The reason we're `instance_exec`ing the matcher is for cases such as
time zone aware attributes, where a decorator is defined in a parent
class, and a method called in the matcher is overridden by a child
class. The matcher will close over the parent, and evaluate in its
context, which is not the behavior we want.
|
|
|
|
|
|
|
| |
This reverts commit dd3ea17191e316aeebddaa7b176f6cfeee7a6365 and add a
regression test.
Fixes #15418
|
|\
| |
| |
| |
| |
| |
| |
| | |
Rename `property` to `attribute`
Conflicts:
activerecord/lib/active_record/attribute_methods/serialization.rb
activerecord/lib/active_record/base.rb
|
| |
| |
| |
| | |
For consistency with https://github.com/rails/rails/pull/15557
|
|/
|
|
|
|
| |
We need to decorate the types lazily. This is extracted to a separate
API, as there are other refactorings that will be able to make use of
it, and to allow unit testing the finer points more granularly.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As a result of all of the refactoring that's been done, it's now
possible for us to define a public API to allow users to specify
behavior. This is an initial implementation so that I can work off of it
in smaller pieces for additional features/refactorings.
The current behavior will continue to stay the same, though I'd like to
refactor towards the automatic schema detection being built off of this
API, and add the ability to opt out of automatic schema detection.
Use cases:
- We can deprecate a lot of the edge cases around types, now that there
is an alternate path for users who wish to maintain the same behavior.
- I intend to refactor serialized columns to be built on top of this
API.
- Gem and library maintainers are able to interact with `ActiveRecord`
at a slightly lower level in a more stable way.
- Interesting ability to reverse the work flow of adding to the schema.
Model can become the single source of truth for the structure. We can
compare that to what the database says the schema is, diff them, and
generate a migration.
|
|
|
|
|
|
| |
transactions.
Closes #14841.
|
|
|
|
| |
Swap Timestamp/Callbacks order in ActiveRecord::Base
|
| |
|
| |
|
| |
|
|
|
|
| |
map to integers in the database, but can be queried by name
|
| |
|
| |
|
|
|
|
| |
I think that these signs are probably mistake.
|