aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
Commit message (Collapse)AuthorAgeFilesLines
...
| * | Use a single thread for all ConnectionPool ReapersJohn Hawthorn2019-05-171-7/+25
| | | | | | | | | | | | | | | Previously we would spawn one thread per connection pool, which ends up being wasteful for apps with several connection pools.
* | | Merge pull request #36284 from kamipo/fix_eager_loading_with_string_joinsRyuta Kamizono2019-05-153-2/+23
|\ \ \ | | | | | | | | Fix eager loading associations with string joins not to raise NoMethodError
| * | | Fix eager loading associations with string joins not to raise NoMethodErrorRyuta Kamizono2019-05-153-2/+23
| | | | | | | | | | | | | | | | Fixes #34456.
* | | | Don't track implicit `touch` mutationRyuta Kamizono2019-05-133-6/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This partly reverts the effect of d1107f4d. d1107f4d makes `touch` tracks the mutation whether the `touch` is occurred by explicit or not. Existing apps expects that the previous changes tracks only the changes which is explicit action by users. I'd revert the implicit `touch` mutation tracking since I'd not like to break existing apps. Fixes #36219.
* | | | [skip ci] Fix missing punctuation mark and formattingVishal Telangre2019-05-131-1/+1
| | | |
* | | | Merge pull request #36255 from eugeneius/sqlite_savepoint_supportKasper Timm Hansen2019-05-124-7/+5
|\ \ \ \ | | | | | | | | | | Remove SQLite version support caveats [ci skip]
| * | | | Remove SQLite version support caveats [ci skip]Eugene Kenny2019-05-124-7/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since d1a74c1e012ed96f7179e53b9190b7da0a369e11, Active Record requires SQLite version 3.8.0 or greater, so savepoints and partial indexes are always available. That commit also added a runtime version check, so we can remove the minimum version requirement from the internal adapter documentation.
* | | | | Merge pull request #36073 from itsWill/document_update_counters_on_relationRyuta Kamizono2019-05-121-1/+13
|\ \ \ \ \ | |/ / / / |/| | | | document update_counters on relation [ci skip]
| * | | | document update_counters on relation [ci skip]Guilherme Mansur2019-05-111-1/+13
| | | | |
* | | | | Merge branch 'migration-timestamp-fix'Gannon McGibbon2019-05-102-0/+3
|\ \ \ \ \ | |_|_|/ / |/| | | | | | | | | Closes #28707.
| * | | | Add class option timestamps to migration generatorMichael Duchemin2019-02-092-0/+5
| | | | | | | | | | | | | | | | | | | | Fixes GH#28706. Now rails g migration create_users and rails g model User have the same behavior for timestamps since they implement the same migration template. The expected behavior is that this create table migration will create the table with timestamps unless you pass --no-timestamps or --skip-timestamps to the generator. The expected migration should match what you get when you use the model generator. Using the migration generator, which doesn't have a class_option for timestamps would cause them to not be added to the migration file. Now the migration behavior of the migration generator, create_table only, is aligned with the migration behavior of the model generator. Also modified relevant example of ActiveRecord Migrations Guide.
* | | | | Remove ignored_sql from SQLCounter by adding "TRANSACTION" to log nameYasuo Honda2019-05-086-23/+15
| |_|/ / |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit adds "TRANSACTION" to savepoint and commit, rollback statements because none of savepoint statements were removed by #36153 since they are not "SCHEMA" statements. Although, only savepoint statements can be labeled as "TRANSACTION" I think all of transaction related method should add this label. Follow up #36153
* | | | Properly give defaults for DatabaseSelector optionsAkira Matsuda2019-05-071-3/+3
| | | | | | | | | | | | | | | | | | | | The initializer receives `nil` for these options when no cofigurations were given: https://github.com/rails/rails/blob/v6.0.0.rc1/activerecord/lib/active_record/railtie.rb#L91-L97
* | | | Should attempt `committed!`/`rolledback!` to all enrolled records in the ↵Ryuta Kamizono2019-05-074-18/+71
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | transaction Currently, `committed!`/`rolledback!` will only be attempted for the first enrolled record in the transaction, that will cause some problematic behaviors. The first one problem, `clear_transaction_record_state` won't be called even if the transaction is finalized except the first enrolled record. This means that de-duplicated records in the transaction won't refer latest state (e.g. won't happen rolling back record state). The second one problem, the enrolled order is not always the same as the order in which the actions actually happened, the first enrolled record may succeed no actions (e.g. `destroy` has already succeeded on another record during `before_destroy`), it will lose to fire any transactional callbacks. To avoid both problems, we should attempt `committed!`/`rolledback!` to all enrolled records in the transaction.
* | | | Remove redundant `test_too_many_binds`Yasuo Honda2019-05-031-20/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | with `ActiveRecord::BindParameterTest#test_too_many_binds` sqlite adapter has its own `bind_params_length`, `ActiveRecord::BindParameterTest#test_too_many_binds` respects it. * Modified `ActiveRecord::BindParameterTest#test_too_many_binds` to show `bind_params_length` value ``` $ git diff diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb index 85685d1d00..83cd07f1d7 100644 --- a/activerecord/test/cases/bind_parameter_test.rb +++ b/activerecord/test/cases/bind_parameter_test.rb @@ -108,6 +108,7 @@ def test_statement_cache_with_sql_string_literal def test_too_many_binds bind_params_length = @connection.send(:bind_params_length) + p bind_params_length topics = Topic.where(id: (1 .. bind_params_length).to_a << 2**63) assert_equal Topic.count, topics.count $ ``` * Executed modified `ActiveRecord::BindParameterTest#test_too_many_binds` ``` $ bin/test test/cases/bind_parameter_test.rb -n test_too_many_binds Using sqlite3 Run options: -n test_too_many_binds --seed 47321 999 . Finished in 0.075249s, 13.2892 runs/s, 26.5784 assertions/s. 1 runs, 2 assertions, 0 failures, 0 errors, 0 skips $ ```
* | | | Namespace association extension modules under the owner modelJean Boussier2019-05-023-12/+12
| | | |
* | | | Make scope arity check consistent (#36134)Rob Trame2019-05-013-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Make scope arity check consistent * Add test for arity change [Rob Trame + Rafael Mendonça França]
* | | | Remove database specific sql statements from SQLCounterYasuo Honda2019-05-013-19/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Every database executes different type of sql statement to get metadata then `ActiveRecord::TestCase` ignores these database specific sql statements to make `assert_queries` or `assert_no_queries` work consistently. Connection adapter already labels these statement by setting "SCHEMA" argument, this pull request makes use of "SCHEMA" argument to ignore metadata queries. Here are the details of these changes: * PostgresqlConnectionTest Each of PostgresqlConnectionTest modified just executes corresponding methods https://github.com/rails/rails/blob/fef174f5c524edacbcad846d68400e7fe114a15a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#L182-L195 ```ruby # Returns the current database encoding format. def encoding query_value("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database()", "SCHEMA") end # Returns the current database collation. def collation query_value("SELECT datcollate FROM pg_database WHERE datname = current_database()", "SCHEMA") end # Returns the current database ctype. def ctype query_value("SELECT datctype FROM pg_database WHERE datname = current_database()", "SCHEMA") end ``` * BulkAlterTableMigrationsTest mysql2 adapter executes `SHOW KEYS FROM ...` to see if there is an index already created as below. I think the main concerns of these tests are how each database adapter creates or drops indexes then ignoring `SHOW KEYS FROM` statement makes sense. https://github.com/rails/rails/blob/fef174f5c524edacbcad846d68400e7fe114a15a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb#L11 ```ruby execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", "SCHEMA") do |result| ``` * Temporary change not included in this commit to show which statements executed ```diff $ git diff diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 8e8ed494d9..df05f9bd16 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -854,7 +854,7 @@ def test_adding_indexes classname = ActiveRecord::Base.connection.class.name[/[^:]*$/] expected_query_count = { - "Mysql2Adapter" => 3, # Adding an index fires a query every time to check if an index already exists or not + "Mysql2Adapter" => 1, # Adding an index fires a query every time to check if an index already exists or not "PostgreSQLAdapter" => 2, }.fetch(classname) { raise "need an expected query count for #{classname}" @@ -886,7 +886,7 @@ def test_removing_index classname = ActiveRecord::Base.connection.class.name[/[^:]*$/] expected_query_count = { - "Mysql2Adapter" => 3, # Adding an index fires a query every time to check if an index already exists or not + "Mysql2Adapter" => 1, # Adding an index fires a query every time to check if an index already exists or not "PostgreSQLAdapter" => 2, }.fetch(classname) { raise "need an expected query count for #{classname}" $ ``` * Executed these modified tests ```ruby $ ARCONN=mysql2 bin/test test/cases/migration_test.rb -n /index/ Using mysql2 Run options: -n /index/ --seed 8462 F Failure: BulkAlterTableMigrationsTest#test_adding_indexes [/home/yahonda/git/rails/activerecord/test/cases/migration_test.rb:863]: 3 instead of 1 queries were executed. Queries: SHOW KEYS FROM `delete_me` SHOW KEYS FROM `delete_me` ALTER TABLE `delete_me` ADD UNIQUE INDEX `awesome_username_index` (`username`), ADD INDEX `index_delete_me_on_name_and_age` (`name`, `age`). Expected: 1 Actual: 3 bin/test test/cases/migration_test.rb:848 F Failure: BulkAlterTableMigrationsTest#test_removing_index [/home/yahonda/git/rails/activerecord/test/cases/migration_test.rb:895]: 3 instead of 1 queries were executed. Queries: SHOW KEYS FROM `delete_me` SHOW KEYS FROM `delete_me` ALTER TABLE `delete_me` DROP INDEX `index_delete_me_on_name`, ADD UNIQUE INDEX `new_name_index` (`name`). Expected: 1 Actual: 3 bin/test test/cases/migration_test.rb:879 .. Finished in 0.379245s, 10.5473 runs/s, 7.9105 assertions/s. 4 runs, 3 assertions, 2 failures, 0 errors, 0 skips $ ``` * ActiveRecord::ConnectionAdapters::Savepoints Left `self.ignored_sql` to ignore savepoint related statements because these SQL statements are not related "SCHEMA" ``` self.ignored_sql = [/^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/] ``` https://github.com/rails/rails/blob/fef174f5c524edacbcad846d68400e7fe114a15a/activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb#L10-L20 ```ruby def create_savepoint(name = current_savepoint_name) execute("SAVEPOINT #{name}") end def exec_rollback_to_savepoint(name = current_savepoint_name) execute("ROLLBACK TO SAVEPOINT #{name}") end def release_savepoint(name = current_savepoint_name) execute("RELEASE SAVEPOINT #{name}") end ```
* | | | Should take the record's state of first action in the transactionRyuta Kamizono2019-04-302-8/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the same id's records are saved and/or destroyed in the transaction, commit callbackes will only run for the first enrolled record. https://github.com/rails/rails/blob/a023e2180093ebc517a642aaf21f3c7241c67657/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L115-L119 The regression #36132 is caused due to #35920 changed the enrollment order that the first action's record will be enrolled to last in the transaction. We could not change the the enrollment order as long as someone depends on the enrollment order. Fixes #36132.
* | | | Fix rubocop offencesRyuta Kamizono2019-04-301-2/+2
| | | |
* | | | Extract `_raise_record_not_touched_error`Ryuta Kamizono2019-04-292-16/+13
| | | |
* | | | Fix merging left_joins to maintain its own `join_type` contextRyuta Kamizono2019-04-276-17/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes a regression for #35864. Usually, stashed joins (mainly eager loading) are performed as LEFT JOINs. But the case of merging joins/left_joins of different class, that (stashed) joins are performed as the same `join_type` as the parent context for now. Since #35864, both (joins/left_joins) stashed joins might be contained in `joins_values`, so each stashed joins should maintain its own `join_type` context. Fixes #36103.
* | | | Merge pull request #32313 from lulalala/model_error_as_objectRafael França2019-04-245-35/+34
|\ \ \ \ | | | | | | | | | | Model error as object
| * | | | Assert deprecationlulalala2019-03-311-2/+2
| | | | |
| * | | | Raise deprecation for calling `[:f] = 'b'` or `[:f] << 'b'`lulalala2019-03-312-12/+16
| | | | | | | | | | | | | | | | | | | | Revert some tests to ensure back compatibility
| * | | | Allow errors to remove duplicates, and ensure cyclic associations w/ ↵lulalala2019-03-311-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | autosave duplicate errors can be removed See SHA 7550f0a016ee6647aaa76c0c0ae30bebc3867288
| * | | | Fix spec as generate_message is no longer called during validationlulalala2019-03-311-0/+2
| | | | |
| * | | | Use errors#import instead of manipulating errors/details hashlulalala2019-03-311-13/+8
| | | | |
| * | | | Fix misalignment caused by SHA eebb9ddf9ba559a510975c486fe59a4edc9da97dlulalala2019-03-311-5/+5
| | | | |
* | | | | Start Rails 6.1 developmentRafael Mendonça França2019-04-243-948/+7
| | | | |
* | | | | Merge pull request #35869 from ↵Ryuta Kamizono2019-04-255-4/+81
|\ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | abhaynikam/35866-add-touch-option-for-has-one-association Adds missing touch option to has_one association
| * | | | | Adds touch option to has_one associationAbhay Nikam2019-04-255-4/+81
| | | | | |
* | | | | | Avoid redundant `attribute_alias?` before `attribute_alias`Ryuta Kamizono2019-04-248-21/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we want to get alias resolved attribute finally, we can use `attribute_alias` directly. For that purpose, avoiding redundant `attribute_alias?` makes alias attribute access 40% faster. https://gist.github.com/kamipo/e427f080a27b46f50bc508fae3612a0e Before (2c0729d8): ``` Warming up -------------------------------------- user['id'] 102.668k i/100ms user['new_id'] 80.660k i/100ms user['name'] 99.368k i/100ms user['new_name'] 81.626k i/100ms Calculating ------------------------------------- user['id'] 1.431M (± 4.0%) i/s - 7.187M in 5.031985s user['new_id'] 1.042M (± 4.2%) i/s - 5.243M in 5.039858s user['name'] 1.406M (± 5.6%) i/s - 7.055M in 5.036743s user['new_name'] 1.074M (± 3.6%) i/s - 5.387M in 5.024152s ``` After (this change): ``` Warming up -------------------------------------- user['id'] 109.775k i/100ms user['new_id'] 103.303k i/100ms user['name'] 105.988k i/100ms user['new_name'] 99.618k i/100ms Calculating ------------------------------------- user['id'] 1.520M (± 6.7%) i/s - 7.574M in 5.011496s user['new_id'] 1.485M (± 6.2%) i/s - 7.438M in 5.036252s user['name'] 1.538M (± 5.4%) i/s - 7.737M in 5.049765s user['new_name'] 1.516M (± 4.6%) i/s - 7.571M in 5.007293s ```
* | | | | | Fix sliced IN clauses to be groupedRyuta Kamizono2019-04-2410-167/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Follow up of #35838. And also this refactors `in_clause_length` handling is entirely integrated in Arel visitor.
* | | | | | Re-organize `init_internals`Ryuta Kamizono2019-04-241-5/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Avoid duplicated `@new_record` assignment * Extract `define_attribute_methods` into `init_internals`
* | | | | | Simplify restore state conditionRyuta Kamizono2019-04-241-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | Follow up to b1458218c95d85c4ce911dd3e99da5ae7cf7aeee.
* | | | | | Lazy allocate `@_start_transaction_state`Ryuta Kamizono2019-04-242-8/+10
|/ / / / /
* | | | | Merge pull request #36070 from imechemi/fix-minor-api-docRyuta Kamizono2019-04-241-1/+1
|\ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | Minor API doc fix [ci skip]
| * | | | | Fix rdoc rendering for push alias symbolTenzin Chemi2019-04-231-1/+1
| | |_|/ / | |/| | |
* / | | | Rename local variable `n` to `name`Ryuta Kamizono2019-04-242-3/+3
|/ / / /
* | | | Make association builder methods privateRyuta Kamizono2019-04-247-1/+16
| | | |
* | | | Merge pull request #36029 from kamipo/deprecate_where_notRyuta Kamizono2019-04-235-15/+118
|\ \ \ \ | | | | | | | | | | Deprecate `where.not` working as NOR and will be changed to NAND in Rails 6.1
| * | | | Deprecate `where.not` working as NOR and will be changed to NAND in Rails 6.1Ryuta Kamizono2019-04-195-15/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `where.not` with polymorphic association is partly fixed incidentally at 213796f (refer #33493, #26207, #17010, #16983, #14161), and I've added test case e9ba12f to avoid lose that fix accidentally in the future. In Rails 5.2, `where.not(polymorphic: object)` works as expected as NAND, but `where.not(polymorphic_type: object.class.polymorphic_name, polymorphic_id: object.id)` still unexpectedly works as NOR. To will make `where.not` working desiredly as NAND in Rails 6.1, this deprecates `where.not` working as NOR. If people want to continue NOR conditions, we'd encourage to them to `where.not` each conditions manually. ```ruby all = [treasures(:diamond), treasures(:sapphire), cars(:honda), treasures(:sapphire)] assert_equal all, PriceEstimate.all.map(&:estimate_of) ``` In Rails 6.0: ```ruby sapphire = treasures(:sapphire) nor = all.reject { |e| e.estimate_of_type == sapphire.class.polymorphic_name }.reject { |e| e.estimate_of_id == sapphire.id } assert_equal [cars(:honda)], nor without_sapphire = PriceEstimate.where.not( estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id ) assert_equal nor, without_sapphire.map(&:estimate_of) ``` In Rails 6.1: ```ruby sapphire = treasures(:sapphire) nand = all - [sapphire] assert_equal [treasures(:diamond), cars(:honda)], nand without_sapphire = PriceEstimate.where.not( estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id ) assert_equal nand, without_sapphire.map(&:estimate_of) ``` Resolves #31209.
* | | | | Avoid new string instance creation in `InsertAll#execute`Ryuta Kamizono2019-04-221-3/+3
| | | | |
* | | | | Don't table name qualify aggrigate column for virtual attributeRyuta Kamizono2019-04-221-4/+2
| | | | | | | | | | | | | | | | | | | | Related 0ee96d13de29680e148ccb8e5b68025f29fd091c.
* | | | | Merge pull request #36052 from kamipo/fast_idRyuta Kamizono2019-04-229-26/+30
|\ \ \ \ \ | | | | | | | | | | | | PERF: 20% faster pk attribute access
| * | | | | PERF: 20% faster pk attribute accessRyuta Kamizono2019-04-229-26/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I've realized that `user.id` is 20% slower than `user.name` in the benchmark (https://github.com/rails/rails/pull/35987#issuecomment-483882480). The reason that performance difference is that `self.class.primary_key` method call is a bit slow. Avoiding that method call will make almost attribute access faster and `user.id` will be completely the same performance with `user.name`. Before (02b5b8cb): ``` Warming up -------------------------------------- user.id 140.535k i/100ms user['id'] 96.549k i/100ms user.name 158.110k i/100ms user['name'] 94.507k i/100ms user.changed? 19.003k i/100ms user.saved_changes? 25.404k i/100ms Calculating ------------------------------------- user.id 2.231M (± 0.9%) i/s - 11.243M in 5.040066s user['id'] 1.310M (± 1.3%) i/s - 6.565M in 5.012607s user.name 2.683M (± 1.2%) i/s - 13.439M in 5.009392s user['name'] 1.322M (± 0.9%) i/s - 6.615M in 5.003239s user.changed? 201.999k (±10.9%) i/s - 1.007M in 5.091195s user.saved_changes? 258.214k (±17.1%) i/s - 1.245M in 5.007421s ``` After (this change): ``` Warming up -------------------------------------- user.id 158.364k i/100ms user['id'] 106.412k i/100ms user.name 158.644k i/100ms user['name'] 107.518k i/100ms user.changed? 19.082k i/100ms user.saved_changes? 24.886k i/100ms Calculating ------------------------------------- user.id 2.768M (± 1.1%) i/s - 13.936M in 5.034957s user['id'] 1.507M (± 2.1%) i/s - 7.555M in 5.017211s user.name 2.727M (± 1.5%) i/s - 13.643M in 5.004766s user['name'] 1.521M (± 1.3%) i/s - 7.634M in 5.018321s user.changed? 200.865k (±11.1%) i/s - 992.264k in 5.044868s user.saved_changes? 269.652k (±10.5%) i/s - 1.344M in 5.077972s ```
* | | | | | Remove useless `set_value` / `get_value` helper methodsRyuta Kamizono2019-04-222-17/+10
|/ / / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Those helper methods makes relation values access 15% slower. https://gist.github.com/kamipo/e64439f7a206e1c5b5c69d92d982828e Before (02b5b8cb): ``` Warming up -------------------------------------- #limit_value 237.074k i/100ms #limit_value = 1 222.052k i/100ms Calculating ------------------------------------- #limit_value 6.477M (± 2.9%) i/s - 32.479M in 5.019475s #limit_value = 1 5.297M (± 4.3%) i/s - 26.424M in 4.999933s ``` After (this change): ``` Warming up -------------------------------------- #limit_value 261.109k i/100ms #limit_value = 1 239.646k i/100ms Calculating ------------------------------------- #limit_value 7.412M (± 1.6%) i/s - 37.077M in 5.003345s #limit_value = 1 6.134M (± 1.0%) i/s - 30.675M in 5.000908s ```
* | | | | Remove never used `database_selector` class accessorRyuta Kamizono2019-04-221-1/+0
| | | | | | | | | | | | | | | | | | | | It was never used from the beginning.
* | | | | Avoid method call if `@transaction_state` is not finalizedRyuta Kamizono2019-04-217-14/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Method call in Ruby is a bit slow. This makes attribute access 10% faster by avoiding method call (`sync_with_transaction_state`). Before (96cf7e0e): ``` Warming up -------------------------------------- user.id 131.291k i/100ms user['id'] 91.786k i/100ms user.name 151.605k i/100ms user['name'] 92.664k i/100ms user.changed? 17.772k i/100ms user.saved_changes? 23.909k i/100ms Calculating ------------------------------------- user.id 1.988M (± 7.0%) i/s - 9.978M in 5.051474s user['id'] 1.155M (± 5.8%) i/s - 5.783M in 5.022672s user.name 2.450M (± 4.3%) i/s - 12.280M in 5.021234s user['name'] 1.263M (± 2.1%) i/s - 6.394M in 5.066638s user.changed? 175.070k (±13.3%) i/s - 853.056k in 5.011555s user.saved_changes? 259.114k (±11.8%) i/s - 1.267M in 5.001260s ``` After (this change): ``` Warming up -------------------------------------- user.id 137.625k i/100ms user['id'] 96.054k i/100ms user.name 156.379k i/100ms user['name'] 94.795k i/100ms user.changed? 18.172k i/100ms user.saved_changes? 24.337k i/100ms Calculating ------------------------------------- user.id 2.201M (± 0.5%) i/s - 11.010M in 5.002955s user['id'] 1.320M (± 1.0%) i/s - 6.628M in 5.021293s user.name 2.677M (± 1.6%) i/s - 13.449M in 5.024399s user['name'] 1.314M (± 1.8%) i/s - 6.636M in 5.051444s user.changed? 190.588k (±11.1%) i/s - 944.944k in 5.065848s user.saved_changes? 262.782k (±12.1%) i/s - 1.290M in 5.028080s ```