| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
|
|
|
| |
[ci skip]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
refs: https://github.com/rails/rails/pull/30161
```
$ echo "+@size+" | rdoc --pipe
<p>+@size+</p>
$ echo "<tt>@size</tt>" | rdoc --pipe
<p><code>@size</code></p>
```
[ci skip]
|
|\
| |
| | |
Sync transaction state when accessing primary key
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
If a record is modified inside a transaction, it must check the outcome
of that transaction before accessing any state which would no longer be
valid if it was rolled back.
For example, consider a new record that was saved inside a transaction
which was later rolled back: it should be restored to its previous state
so that saving it again inserts a new row into the database instead of
trying to update a row that no longer exists.
The `id` and `id=` methods defined on the PrimaryKey module implement
this correctly, but when a model uses a custom primary key, the reader
and writer methods for that attribute must check the transaction state
too. The `read_attribute` and `write_attribute` methods also need to
check the transaction state when accessing the primary key.
|
|/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Let's say you have a nested transaction and both records are saved.
Before the outer transaction closes, a rollback is performed. Previously
the record in the outer transaction would get marked as not persisted
but the inner transaction would get persisted.
```ruby
Post.transaction do
post_one.save # will get rolled back
Post.transaction(requires_new: true) do
post_two.save # incorrectly remains marked as persisted
end
raise ActiveRecord::Rollback
end
```
To fix this the PR changes transaction handling to have the child
transaction ask the parent how the records should be marked. When
there are child transactions, it will always be a SavpointTransaction
because the stack isn't empty. From there we pass the parent_transaction
to the child SavepointTransaction where we add the children to the parent
so the parent can mark the inner transaction as rolledback and thus mark
the record as not persisted.
`update_attributes_from_transaction_state` uses the `completed?` check to
correctly mark all the transactions as rolledback and the inner record as
not persisted.
```ruby
Post.transaction do
post_one.save # will get rolled back
Post.transaction(requires_new: true) do
post_two.save # with new behavior, correctly marked as not persisted
on rollback
end
raise ActiveRecord::Rollback
end
```
Fixes #29320
|
|
|
|
|
| |
This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing
changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
|
| |
|
|
|
|
|
| |
The old top level classes PGconn, PGresult and PGError were deprecated
since pg-0.13.0: https://github.com/ged/ruby-pg/blob/master/History.rdoc#v0130-2012-02-09-michael-granger-gedfaeriemudorg
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
Race conditions can occur when an ActiveRecord is destroyed
twice or destroyed and updated. The callbacks should only be
triggered once, similar to a SQL database trigger.
|
|
|
|
|
|
| |
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But comments was still kept absolute position. This commit aligns
comments with method definitions for consistency.
|
| |
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
| |
|
|
|
|
|
|
|
|
| |
Just noticed this on the [edge API].
[ci skip]
[edge API]: http://edgeapi.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Those are actually shortcuts for `after_commit`.
Before:
after_commit :add_to_index_later, on: :create
after_commit :update_in_index_later, on: :update
after_commit :remove_from_index_later, on: :destroy
After:
after_create_commit :add_to_index_later
after_update_commit :update_in_index_later
after_destroy_commit :remove_from_index_later
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
| |
Rails 4.2.3 AS::Callbacks will not halt chain if `false` is returned.
That is the behavior of specific callbacks like AR::Callbacks and
AM::Callbacks.
|
|
|
|
|
| |
skip]
Bumps from `5.6` to `5.7`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This clears the transaction record state when the transaction finishes
with a `:committed` status.
Considering the following example where `name` is a required attribute.
Before we had `new_record?` returning `true` for a persisted record:
```ruby
author = Author.create! name: 'foo'
author.name = nil
author.save # => false
author.new_record? # => true
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit bdc1d329d4eea823d07cf010064bd19c07099ff3.
Before:
Calculating -------------------------------------
22.000 i/100ms
-------------------------------------------------
229.700 (± 0.4%) i/s - 1.166k
Total Allocated Object: 9939
After:
Calculating -------------------------------------
24.000 i/100ms
-------------------------------------------------
246.443 (± 0.8%) i/s - 1.248k
Total Allocated Object: 7939
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
# gem 'rails', github: 'rails/rails', ref: 'bdc1d329d4eea823d07cf010064bd19c07099ff3'
gem 'rails', github: 'rails/rails', ref: 'd2876141d08341ec67cf6a11a073d1acfb920de7'
gem 'arel', github: 'rails/arel'
gem 'sqlite3'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('sqlite3::memory:')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.boolean :admin
t.timestamps null: false
end
end
class User < ActiveRecord::Base
default_scope { where(admin: true) }
end
admin = true
1000.times do
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
admin: admin
}
User.create!(attributes)
admin = !admin
end
GC.disable
Benchmark.ips(5, 3) do |x|
x.report { User.all.to_a }
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.all.to_a
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
|
| |
|
|
|
|
|
| |
See commit 890da514, this is not intended.
So fix indent.
|
|
|
|
| |
This reverts commit 796cab45561fce268aa74e6587cdb9cae3bb243e.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
This reverts commit 393e65b4170608593ad82377a9eadc918e85698d and
ec51c3fedd16b561d096dcc1a6705fdc02ab7666
We don't want the records to hold hard references to transactions
because they point at records that have callbacks.
|
|
|
|
|
| |
this way we don't have to mutate a state object, we can just change the
state of the txn
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We only set the state on the record if that condition is `false` in the
first place, so we dont need to call that again. Also that call is
expensive, follow benchmark with before and after this change:
```
Calculating -------------------------------------
persisted? 15.272k i/100ms
-------------------------------------------------
persisted? 350.119k (± 4.6%) i/s - 1.756M
```
```
Calculating -------------------------------------
persisted? 25.988k i/100ms
-------------------------------------------------
persisted? 1.294M (± 5.3%) i/s - 6.445M
```
(benchmark borrowed from 57d35b2bf9e48173a5f97ccff5e6897f0c46411f)
|
|
|
|
|
| |
depth is always 0, so the index will always be false. No reason to
create the instance variable if it isn't used
|
| |
|
|
|
|
| |
[fixes #18903]
|
|
|
|
|
|
|
|
|
| |
Add after_commit_without_transaction_enrollment and
after_rollback_without_transaction_enrollment private callbacks so we
can create after_commit and after_rollback callbacks without having the
records automatic enrolled in the transaction.
[fixes #18904]
|
| |
|
|
|
|
|
| |
the transaction object shouldn't know so much about active record
objects, so let's push the conditionals in to the instance.
|
| |
|
|
|
|
| |
As discussed before, those methods should receive a keyword args instead of just parameters
|
|\
| |
| | |
Fix rollback of primarykey-less tables
|
| |
| |
| | |
If you have a table without a primary key, and an `after_commit` callback on that table (ie `has_transactional_callbacks?` returns true), then trying to rollback a transaction involving that record would result in “ActiveModel::MissingAttributeError: can't write unknown attribute ``”
|
|/
|
|
|
|
|
|
| |
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.
|