aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
Commit message (Collapse)AuthorAgeFilesLines
* fix doc about ActiveRecord::Transactions::ClassMethods#transaction [ci skip]Mehmet Emin İNAÇ2015-07-201-2/+1
|
* Merge pull request #20946 from schneems/schneems/let-it-goSean Griffin2015-07-196-8/+8
|\ | | | | Freeze string literals when not mutated.
| * Freeze string literals when not mutated.schneems2015-07-196-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution? To look at memory: ```ruby require 'get_process_mem' mem = GetProcessMem.new GC.start GC.disable 1_114.times { " " } before = mem.mb after = mem.mb GC.enable puts "Diff: #{after - before} mb" ``` Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests. To look at raw speed: ```ruby require 'benchmark/ips' number_of_objects_reduced = 1_114 Benchmark.ips do |x| x.report("freeze") { number_of_objects_reduced.times { " ".freeze } } x.report("no-freeze") { number_of_objects_reduced.times { " " } } end ``` We get the results ``` Calculating ------------------------------------- freeze 1.428k i/100ms no-freeze 609.000 i/100ms ------------------------------------------------- freeze 14.363k (± 8.5%) i/s - 71.400k no-freeze 6.084k (± 8.1%) i/s - 30.450k ``` Now we can do some maths: ```ruby ips = 6_226k # iterations / 1 second call_time_before = 1.0 / ips # seconds per iteration ips = 15_254 # iterations / 1 second call_time_after = 1.0 / ips # seconds per iteration diff = call_time_before - call_time_after number_of_objects_reduced * diff * 100 # => 0.4530373333993266 miliseconds saved per request ``` So we're shaving off 1 second of execution time for every 220 requests. Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep. p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings. Keep those strings Frozen ![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
* | Fix counter_cache for polymorphic associationsStefan Kanev2015-07-191-4/+12
|/ | | | | | | | | | | | | | Also removes a false positive test that depends on the fixed bug: At this time, counter_cache does not work with polymorphic relationships (which is a bug). The test was added to make sure that no StaleObjectError is raised when the car is destroyed. No such error is currently raised because the lock version is not incremented by appending a wheel to the car. Furthermore, `assert_difference` succeeds because `car.wheels.count` does not check the counter cache, but the collection size. The test will fail if it is replaced with `car.wheels_count || 0`.
* Merge pull request #20924 from andrii/masterAbdelkader Boudih2015-07-191-1/+1
|\ | | | | [ci skip] Fix typo in #any? RDoc
| * [ci skip] Fix typo in #any? RDocAndrii Ponomarov2015-07-171-1/+1
| |
* | Merge pull request #20932 from twalpole/collection_association_parametersSean Griffin2015-07-181-0/+6
|\ \ | | | | | | Ensure that 'ActionController::Parameters' can still be passed to AR …
| * | Ensure that 'ActionController::Parameters' can still be passed to AR for ↵Thomas Walpole2015-07-181-0/+6
| | | | | | | | | | | | collection associations
* | | Ensure cyclic associations w/ autosave don't cause duplicate errorsSean Griffin2015-07-181-0/+7
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This code is so fucked. Things that cause this bug not to replicate: - Defining the validation before the association (we end up calling `uniq!` on the errors in the autosave validation) - Adding `accepts_nested_attributes_for` (I have no clue why. The only thing it does that should affect this is adds `autosave: true` to the inverse reflection, and doing that manually doesn't fix this). This solution is a hack, and I'm almost certain there's a better way to go about it, but this shouldn't cause a huge hit on validation times, and is the simplest way to get it done. Fixes #20874.
* / Ensure that `ActionController::Parameters` can still be passed to ARSean Griffin2015-07-181-0/+3
|/ | | | | | | | | | | | | | | | | | | | | Since nested hashes are also instances of `ActionController::Parameters`, and we're explicitly looking to work with a hash for nested attributes, this caused breakage in several points. This is the minimum viable fix for the issue (and one that I'm not terribly fond of). I can't think of a better place to handle this at the moment. I'd prefer to use some sort of solution that doesn't special case AC::Parameters, but we can't use something like `to_h` or `to_a` since `Enumerable` adds both. While I've added a trivial test case for verifying this fix in isolation, we really need better integration coverage to prevent regressions like this in the future. We don't actually have a lot of great places for integration coverage at the moment, so I'm deferring it for now. Fixes #20922.
* Deprecate force association reload by passing truePrem Sichanugrist2015-07-152-0/+16
| | | | | | | | | | | | | | | | | | This is to simplify the association API, as you can call `reload` on the association proxy or the parent object to get the same result. For collection association, you can call `#reload` on association proxy to force a reload: @user.posts.reload # Instead of @user.posts(true) For singular association, you can call `#reload` on the parent object to clear its association cache then call the association method: @user.reload.profile # Instead of @user.profile(true) Passing a truthy argument to force association to reload will be removed in Rails 5.1.
* Revert "Revert "Reduce allocations when running AR callbacks.""Guo Xiang Tan2015-07-165-18/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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}" ```
* Fix regression caused by a01d164bRafael Mendonça França2015-07-071-2/+2
| | | | | | | | | When preload is used in a default scope the preload_values were returning nested arrays and causing the preloader to fail because it doesn't know how to deal with nested arrays. So before calling preload! we need to splat the arguments. This is not needed to includes because it flatten its arguments.
* [skip ci] #distinct instead of #uniqJon Atack2015-07-031-2/+3
| | | | | | | | as #uniq will be removed from Rails 5.0 as per the Active Support exception raised: ActiveSupport::DeprecationException: DEPRECATION WARNING: uniq is deprecated and will be removed from Rails 5.0 (use distinct instead).
* Use default model enum in fixtures if not definedeileencodes2015-07-021-1/+3
| | | | | | | | | | | After 908cfef was introduced fixtures that did not set an enum would return nil instead of the default enum value. The fixtures should assume the default if a different enum is not defined. The change checks first if the enum is defined in the fixture before setting it based on the fixture.
* Correct through associations using scopesSean Griffin2015-06-302-6/+1
| | | | | | | | | | | | | | | | | | | | | | The changes introduced to through associations in c80487eb were quite interesting. Changing `relation.merge!(scope)` to `relation = relation.merge(scope)` should in theory never cause any changes in behavior. The subtle breakage led to a surprising conclusion. The old code wasn't doing anything! Since `merge!` calls `instance_exec` when given a proc, and most scopes will look something like `has_many :foos, -> { where(foo: :bar) }`, if we're not capturing the return value, it's a no-op. However, removing the `merge` causes `unscope` to break. While we're merging in the rest of the chain elsewhere, we were never merging in `unscope` values, causing a breakage on associations where a default scope was being unscoped in an association scope (yuk!). This is subtly related to #20722, since it appears we were previously relying on this mutability. Fixes #20721. Fixes #20727.
* follow-up to 2183caa, always reenable the task. #20743Yves Senn2015-06-301-3/+3
|
* `dump_schema_after_migration` applies migration tasks other than db:migrateYves Senn2015-06-301-9/+12
| | | | | | | | | | | | | Closes #20743. The task `db:_dump` now only dumps the schema if `ActiveRecord::Base.dump_schema_after_migration` is true. This has effects: - `db:migrate:up` - `db:migrate:down` - `db:forward` - `db:rollback`
* docs, nodoc `NullPreloader` and `AlreadyLoaded`.Yves Senn2015-06-291-2/+2
| | | | | These classes are part of Active Record Preloader, which is not part of the public API.
* Revert the behavior of association names and `where` to be closer to 4.2Sean Griffin2015-06-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this change, we will always assume the association name is the same as the table it's referencing. This is subtly different than treating the hash key passed to `where` as the table name, as it still allows the class referenced by the association to provide additional type information. After exploring several possible solutions to the ambiguity problem, I do not think there is a short term answer that will maintain backwards compatibility. This change will make it so the following code does not work: class User has_many :approved_posts, -> { where(approved: true) }, class_name: "Post" end User.where(approved_posts: { id: 1 }) But prevents potential ambiguity and collision as demonstrated in [this gist](https://gist.github.com/senny/1ae4d8ea7b0e269ed7a0). Unfortunately, truely solving this requires significantly re-architecting this code, so that what is currently represented as an `Arel::Attribute` is instead another data structure that also references the association it is representing, so we can identify the proper table name for aliasing when we construct the final tree. While I'd still like to accomplish that in the long run, I don't think I'll be able to get there in time for Rails 5 (since I'm not full time OSS any more, and this is several weeks worth of work). I'm hoping to achieve this for Rails 5.1. Fixes #20308
* Merge pull request #20607 from cmtonkinson/update-console-colorsRafael Mendonça França2015-06-271-8/+11
|\ | | | | More granular console SQL coloration
| * More granular console SQL colorationChris Tonkinson2015-06-231-8/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This new coloration approach makes it easier to scan the rails console for specific types of activity with more fine-grained visual cues. Virtual terminal ANSI color escape codes are used when displaying SQL statements in the rails console. The former implementation alternates line prefix information (including the statement name and execution latency) between CYAN and MAGENTA. This visually differentiates any SQL statements in the log and is useful for quickly scanning for database activity. While a great idea and a solid foundation, alternating between just two colors on an even/odd basis (much like striping an HTML table) can be improved upon. This patch replaces the even/odd striping with a more comprehensive scheme that applies coloration based on the type of statement being run. Every statement logged has its prefix (name and latency) colored white (as the statement body was previously). The statement body is now colored according to the nature of the statement: - INSERT statements are GREEN (symbolic of creation or genesis) - SELECT statements are BLUE (typically used for informational displays, as SELECT statements do not normally have side-effects) - DELETE statements are RED (commonly used to indicate the danger of a destructive action) - UPDATE statements are YELLOW (it's like a less extreme RED :P) - TRANSACTION statements are CYAN (arbitrary) - and any other statements are MAGENTA (again, arbitrary)
* | Merge pull request #20699 from ↵Rafael Mendonça França2015-06-272-2/+6
|\ \ | | | | | | | | | | | | vngrs/foreign_key_with_table_name_suffix_and_prefix Add table name prefix and suffix support for foreign keys
| * | Add table name prefix and suffix support to add_foreign_key and ↵Mehmet Emin İNAÇ2015-06-252-2/+6
| | | | | | | | | | | | | | | | | | remove_foreign_key methods fix tests
* | | Merge pull request #20018 from sikachu/change-column-default-recorderRafael Mendonça França2015-06-276-7/+35
|\ \ \ | | | | | | | | Add reversible syntax for change_column_default
| * | | Add reversible syntax for change_column_defaultPrem Sichanugrist2015-06-266-7/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Passing `:from` and `:to` to `change_column_default` makes this command reversible as user has defined its previous state. So, instead of having the migration command as: change_column_default(:posts, :state, "draft") They can write it as: change_column_default(:posts, :state, from: nil, to: "draft")
* | | | Update .pluck documentation on uniqPrem Sichanugrist2015-06-261-1/+1
|/ / / | | | | | | | | | | | | | | | This is to show users that they can chain `.uniq` and `.pluck` to get the `DISTINCT column` result. They don't have to do `DISTINCT column` themselves.
* | / Display decimal defaults as strings to keep precisionJohn Gesimondo2015-06-231-1/+1
| |/ |/|
* | A few documentation fixes [ci skip]Robin Dupret2015-06-231-1/+1
| |
* | Merge pull request #20673 from aditya-kapoor/correct-preload-docYves Senn2015-06-231-1/+1
|\ \ | | | | | | | | | [ci skip] correct for ActiveRecord::Associations::Preloader
| * | [ci skip] correct for ActiveRecord::Associations::Preloader:Aditya Kapoor2015-06-231-1/+2
| | |
* | | docs, add missing closing bracket. [ci skip]Yves Senn2015-06-231-1/+1
|/ /
* | Merge pull request #20552 from jamesdabbs/belongs-to-polymorphic-force-reloadYves Senn2015-06-231-1/+1
|\ \ | | | | | | | | | Fix `undefined method uncached` for polymorphic belongs_to #20426
| * | Fix `undefined method uncached` for polymorphic belongs_to #20426James Dabbs2015-06-131-1/+1
| | | | | | | | | | | | | | | | | | | | | Unitialized polymorphic `belongs_to` associations raise an error while attempting to reload, as they attempt to make an uncached reload, but don't have a klass to fetch uncachedly. In this case, `loaded?` should be `false` anyway.
* | | thrown ActiveRecord::AssociationTypeMismatch when assigning a wrong value ↵Diego Carrion2015-06-221-3/+6
| |/ |/| | | | | | | for a namespaced association fixes #20541
* | refactor, don't duplicate presence validator logic.Yves Senn2015-06-221-10/+4
| | | | | | | | | | This is a small refactoring that simplifies the Active Record specific lenght validator.
* | docs, update Active Model reference for AR length validator. [ci skip]Yves Senn2015-06-221-1/+4
| |
* | AR absence validator respects `marked_for_destruction?`. Closes #20449.Yves Senn2015-06-222-0/+25
| | | | | | | | Associated objects that were marked for destruction are considered absent.
* | Include `Enumerable` in `ActiveRecord::Relation`Sean Griffin2015-06-194-37/+17
| | | | | | | | | | | | | | | | | | | | | | After discussing, we've decided it makes more sense to include it. We're already forwarding every conflicting method to `to_a`, and there's no conflation of concerns. `Enumerable` has no mutating methods, and it just allows us to simplify the code. No existing methods will have a change in behavior. Un-overridden Enumerable methods will simply delegate to `each`. [Sean Griffin & bogdan]
* | Use `Enumerable#sum` on `ActiveRecord::Relation` when a block is givenSean Griffin2015-06-191-2/+6
| | | | | | | | | | | | | | | | This matches our behavior in other cases where useful enumerable methods might have a different definition in `Relation`. Wanting to actually enumerate over the records in this case is completely reasonable, and wanting `.sum` is reasonable for the same reason it is on `Enumerable` in the first place.
* | Merge pull request #20259 from rastasheep/rastasheep-patch-1Yves Senn2015-06-191-2/+2
|\ \ | | | | | | | | | Update documentation for ActiveRecord::Migration#remove_index
| * | Fix typo [ci skip]Aleksandar Diklic2015-05-221-2/+2
| | | | | | | | | | | | `remove_index` works with multiple column names as `add_index`
* | | Merge pull request #19843 from marshall-lee/explain_cte_queriesYves Senn2015-06-191-1/+1
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | Let WITH (CTE) queries be explainable Conflicts: activerecord/CHANGELOG.md
| * | | Let WITH (CTE) queries be explainableVladimir Kochnev2015-05-281-1/+1
| | | |
* | | | Autoload ActiveRecord::RecordInvalidRafael Mendonça França2015-06-181-0/+1
| | | | | | | | | | | | | | | | Fixes #20626
* | | | Fix descriptions of databases.rake [ci skip]Mehmet Emin İNAÇ2015-06-171-11/+11
| | | | | | | | | | | | | | | | revert create and drop task descriptions
* | | | raise ActiveModel::MissingAttributeError when trying to access a ↵Diego Carrion2015-06-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | relationship without the foreign key attribute fixes regression reported on #20253 ActiveRecord::Base#[] was not used cause of 8b95420
* | | | Small refactor on db:resetArthur Neves2015-06-151-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | db:reset should not prematurely load the environment, so, for instance, if there is any initializer that touches th DB, it will not touch that before droping it. Also this makes the code simpler. This changed was made back in 15fb4302b6ff16e641b6279a3530eb8ed97f2899 , not sure why. But I am pretty much sure we should do it like this, as drop and setup should load its dependencies tasks if necessary.
* | | | Merge pull request #20016 from steved/sdavidovitz/abort_if_pendingArthur Nogueira Neves2015-06-151-1/+1
|\ \ \ \ | | | | | | | | | | make sure to load_config for db:abort_if_pending_migrations
| * | | | make sure to load_config for db:abort_if_pending_migrationsSteven Davidovitz2015-05-041-1/+1
| | | | |