Commit Graph

12467 Commits

Author SHA1 Message Date
Kasper Timm Hansen
3bc747bd86 Merge pull request #27551 from kirs/deprecate-class-name-as-class
Deprecate reflection class name to accept a class
2017-01-09 19:58:22 +01:00
Kir Shatrov
8312a0d222 Deprecate reflection class name to accept a class
The idea of `class_name` as an option of reflection is that passing a
string would allow us to lazy autoload the class.

Using `belongs_to :client, class_name: Customer` is eagerloading models more than necessary
and creating possible circular dependencies.
2017-01-09 13:08:33 -05:00
Kasper Timm Hansen
7f19f30819 Merge pull request #25427 from eugeneius/update_increment_documentation
Update increment! documentation [ci skip]
2017-01-08 20:56:38 +01:00
Sean Griffin
11a50f4811 Merge pull request #27598 from NickLaMuro/fix-deep-nesting-where-clauses-with-joins
Fix bug with symbolized keys in .where with nested join
2017-01-07 17:30:34 -05:00
Nick LaMuro
c322b7c2b1 Adds .to_s to table_name call
Avoids a NoMethodError when table_name is a symbol instead of a string.
2017-01-06 17:59:30 -06:00
schneems
93ee268ef4 Preserve up and down return type
In Rails 4.2 calling `ActiveRecord::Migrator.migrate` would return an array of results. Without realizing that this return type was expected I accidentally introduced a change in 4d60e93174

This PR preserves the previous behavior and adds a test on the return type. This will need a backport to 5.0 branch.
2017-01-06 13:30:42 -06:00
Rafael França
b3bd6451b1 Merge pull request #27294 from eavgerinos/doc-ar-callbacks-order
[documentation] ActiveRecord: Document order of Callbacks
2017-01-06 04:39:31 -05:00
Akira Matsuda
5f03172f54 Privatize unneededly protected methods in Active Record 2017-01-05 20:01:02 +09:00
Akira Matsuda
5473e390d3 self. is not needed when calling its own instance method
Actually, private methods cannot be called with `self.`, so it's not just redundant, it's a bad habit in Ruby
2017-01-05 19:58:52 +09:00
Akira Matsuda
d8e0282af9 This method is never called since 8e633e505880755e7e366ccec2210bbe2b5436e7 2017-01-05 18:55:28 +09:00
Ryuta Kamizono
801a21e6c9 Optimizing information_schema query for foreign_keys
Need `table_name` to avoid all databases scan.
See https://dev.mysql.com/doc/refman/5.7/en/information-schema-optimization.html.

```
> EXPLAIN SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key', fk.column_name AS 'column', fk.constraint_name AS 'name', rc.update_rule AS 'on_update', rc.delete_rule AS 'on_delete' FROM information_schema.key_column_usage fk JOIN information_schema.referential_constraints rc USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'activerecord_unittest' AND fk.table_name = 'fk_test_has_pk' AND rc.table_name = 'fk_test_has_pk'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: fk
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA,TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
     filtered: NULL
        Extra: Using where; Open_full_table; Scanned 0 databases
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: rc
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
     filtered: NULL
        Extra: Using where; Open_full_table; Scanned 1 database; Using join buffer (Block Nested Loop)
2 rows in set, 1 warning (0.00 sec)
```

Fixes #27579.
2017-01-05 14:36:48 +09:00
Chris Holmes
f8ab3ae18f Raise error when has_many through is defined before through association
https://github.com/rails/rails/issues/26834

This change raises an error if a has_many through association
is defined before the through association.
2017-01-04 11:56:08 +00:00
Ryuta Kamizono
b334aa0ea4 Fix find_by and where consistency
The alternative of #26213.

Currently `find_by` and `where` with AR object return inconsistent
result. This is caused by statement cache does not support AR object.
Passing to finder method to fix the issue.

Fixes #26210.
2017-01-04 12:27:44 +09:00
Rafael Mendonça França
127509c071
Revert "Merge pull request #21233 from mtsmfm/disable-referential-integrity-without-superuser-privileges"
This reverts commit eeac6151a55cb7d5f799e1ae33aa64a839cbc3aa, reversing
changes made to 5c40239d3104543e70508360d27584a3e4dc5baf.

Reason: Broke the isolated tests.
https://travis-ci.org/rails/rails/builds/188721346
2017-01-03 22:11:16 -05:00
Rafael Mendonça França
b6ffb5efcb
Revert "Merge pull request #27550 from mtsmfm/fix-generator-command-for-nested-rails-engine"
This reverts commit 1e969bfb98b88799e2c759fce25a1d8cf00d7ce7, reversing
changes made to a5041f267ded119c2d00b8786c2f2c1e3f93c8a1.

Reason: It breaks the public API
2017-01-03 21:51:18 -05:00
Rafael França
1e969bfb98 Merge pull request #27550 from mtsmfm/fix-generator-command-for-nested-rails-engine
Fix generator command for nested (namespaced) rails engine
2017-01-03 21:45:25 -05:00
Rafael França
eeac6151a5 Merge pull request #21233 from mtsmfm/disable-referential-integrity-without-superuser-privileges
Use `SET CONSTRAINTS` for `disable_referential_integrity` without superuser privileges
2017-01-03 20:38:50 -05:00
Rafael França
5c40239d31 Merge pull request #25522 from kamipo/fix_select_rows_method_signature_for_consistency
Fix `select_rows` method signature for consistency
2017-01-03 19:48:56 -05:00
Rafael Mendonça França
61b5f5d2f1
Remove unneeded requires at active record 2017-01-03 19:42:36 -05:00
Rafael Mendonça França
fdc219e0f8
Merge pull request #26689 from kamipo/deprecate_passing_name_to_indexes
Deprecate passing `name` to `indexes` like `tables`
2017-01-03 19:25:14 -05:00
Rafael Mendonça França
0df8649f58
Remove deprecation of using ActiveRecord::Base instance in .update 2017-01-03 19:22:52 -05:00
Rafael Mendonça França
e229580b4b
Remove deprecated db:test:clone* tasks 2017-01-03 19:10:31 -05:00
Ryuta Kamizono
457e6c77d4 Deprecate passing name to indexes like tables
Passing `name` to `tables` is already deprecated at #21601.
Passing `name` to `indexes` is also unused.
2017-01-04 08:48:59 +09:00
Ryuta Kamizono
cb1803591e Fix select_rows method signature for consistency
Related #22973, #24708.

`select_all`, `select_one`, `select_value`, and `select_values` method
signature is `(arel, name = nil, binds = [])`.
But `select_rows` is `(sql, name = nil, binds = [])`.
2017-01-04 07:44:45 +09:00
Arthur Nogueira Neves
f8e040957b Merge pull request #26352 from kamipo/avoid_to_call_set_inverse_instance_twice
Avoid to call `set_inverse_instance` twice for `has_many` association
2017-01-03 16:18:45 -05:00
Jon Moss
8ded825bc2 Compare deserialized values for PostgreSQL::OID::Hstore types
Per the regression commit below, the commit changes the behavior of
`#changed?`to consult the `#changed_in_place?` method on `Type::Value` classes.
Per this change, `PostgreSQL::OID::Hstore` needs to override this method
in order to compare the deserialized forms of the two arguments. In
Ruby, two hashes are considered equal even if their key order is
different. This commit helps to bring that behavior to `Hstore` values.

Fixes regression introduced by 8e633e505880755e7e366ccec2210bbe2b5436e7

Fixes #27502
2017-01-03 16:07:47 -05:00
Kasper Timm Hansen
8740c6ea0f [ci skip] Find and record the article! 🤓
Closes #27555.

[ Ben A. Morgan & Kasper Timm Hansen ]
2017-01-03 21:57:39 +01:00
Rafael Mendonça França
4b6709e818
Raise ArgumentError when a instance of ActiveRecord::Base is passed to
find and exists?
2017-01-03 15:53:03 -05:00
Sean Griffin
0f1d0b1b52 Consistently apply adapter behavior when serializing arrays
In f1a0fa9 we moved backend specific timestamp behavior out of the type
and into the adapter. This was in line with our general attempt to
reduce the number of adapter specific type subclasses. However, on PG,
the array type performs all serialization, including database encoding
in its serialize method.

This means that we have converted the value into a string before
reaching the database, so no adapter specific logic can be applied (and
this also means that timestamp arrays were using the default `.to_s`
method on the given object, which likely meant timestamps were being
ignored in certain cases as well)

Ultimately I want to do a more in depth refactoring which separates
database serializer objects from the active model type objects, to give
us a less awkward API for introducing the attributes API onto Active
Model.

However, in the short term, we follow the solution we've applied
elsewhere for this. Move behavior off of the type and into the adapter,
and use a data object to allow the type to communicate information up
the stack.

Fixes #27514.
2017-01-03 11:15:16 -05:00
Sean Griffin
0d8069d365 Merge pull request #27435 from kamipo/follow_up_25307
Active Record supports MySQL >= 5.1.10
2017-01-03 11:19:47 -05:00
Sean Griffin
948cebd017 Merge pull request #27491 from kamipo/add_missing_emit_warning
Add missing `emit_warning_if_needed` for `changed?`
2017-01-03 11:17:16 -05:00
Konstantin Lazarev
cdf8a2b493 Cache results of computing model type
We faced a significant performance decrease when we started using STI
without storing full namespaced class name in type column (because of PostgreSQL
length limit for ENUM types).
We realized that the cause of it is the slow STI model instantiation. Problematic
method appears to be `ActiveRecord::Base.compute_type`, which is used to find
the right class for STI model on every instantiation.
It builds an array of candidate types and then iterates through it calling
`safe_constantize` on every type until it finds appropriate constant. So if
desired type isn't the first element in this array there will be at least one
unsuccessful call to `safe_constantize`, which is very expensive, since it's
defined in terms of `begin; rescue; end`.

This commit is an attempt to speed up `compute_type` method simply by caching
results of previous calls.

```ruby
class MyCompany::MyApp::Business::Accounts::Base < ApplicationRecord
  self.table_name = 'accounts'
  self.store_full_sti_class = false
end

class MyCompany::MyApp::Business::Accounts::Free < Base
end

class MyCompany::MyApp::Business::Accounts::Standard < Base
  # patch .compute_type there
end

puts '======================= .compute_type ======================='
Benchmark.ips do |x|
  x.report("original method") do
    MyCompany::MyApp::Business::Accounts::Free.send :compute_type, 'Free'
  end
  x.report("with types cached") do
    MyCompany::MyApp::Business::Accounts::Standard.send :compute_type, 'Standard'
  end
  x.compare!
end
```

```
======================= .compute_type =======================
  with types cached:  1529019.4 i/s
    original method:     2850.2 i/s - 536.46x  slower
```

```ruby
5_000.times do |i|
  MyCompany::MyApp::Business::Accounts::Standard.create!(name: "standard_#{i}")
end

5_000.times do |i|
  MyCompany::MyApp::Business::Accounts::Free.create!(name: "free_#{i}")
end

puts '====================== .limit(100).to_a ======================='
Benchmark.ips do |x|
  x.report("without .compute_type patch") do
    MyCompany::MyApp::Business::Accounts::Free.limit(100).to_a
  end
  x.report("with .compute_type patch") do
    MyCompany::MyApp::Business::Accounts::Standard.limit(100).to_a
  end
  x.compare!
end
```

```
====================== .limit(100).to_a =======================
     with .compute_type patch:      360.5 i/s
  without .compute_type patch:       24.7 i/s - 14.59x  slower
```
2017-01-03 19:02:38 +05:00
Fumiaki MATSUSHIMA
085546df45 Fix generator command for nested (namespaced) rails engine
If we create nested (namespaced) rails engine such like bukkits-admin,
`bin/rails g scaffold User name:string age:integer`
will create
`bukkits-admin/app/controllers/bukkits/users_controller.rb`
but it should create
`bukkits-admin/app/controllers/bukkits/admin/users_controller.rb`.

In #6643, we changed `namespaced_path` as root path
because we supposed application_controller is always in root
but nested rails engine's application_controller will not.
2017-01-03 21:18:09 +09:00
Ryuta Kamizono
059a476c57 Counter cache touching don't need object finding anymore
`current_time_from_proper_timezone` and timestamp attributes methods was
pushed up to class method.
2017-01-03 04:42:56 +09:00
Ryuta Kamizono
77ff9a0adb Push current_time_from_proper_timezone and timestamp attributes methods up to class method
Actually these methods don't need instantiation.
2017-01-03 04:34:43 +09:00
Ryuta Kamizono
b177427d97 Fix update counters of multiple records with touch: true
Currently does not work the following example in the doc:

```ruby
  # For the Posts with id of 10 and 15, increment the comment_count by 1
  # and update the updated_at value for each counter.
  Post.update_counters [10, 15], comment_count: 1, touch: true
  # Executes the following SQL:
  # UPDATE posts
  #    SET comment_count = COALESCE(comment_count, 0) + 1,
  #    `updated_at` = '2016-10-13T09:59:23-05:00'
  #  WHERE id IN (10, 15)
```
2017-01-03 01:40:04 +09:00
Kasper Timm Hansen
4a36d81385 [ci skip] Use touch; slim wording.
* Rename update -> touch to remain consistent with the other docs
  language of "touch"'ing.
* Remove the sentence that's repeated from just above and rephrase.
2017-01-02 08:48:44 +01:00
Rafael França
2e621f6c91 Merge pull request #27526 from kirs/database-tasks-schema-cache
Dump schema cache for custom connection
2017-01-01 22:55:49 -05:00
kenta-s
3fc7133b24 Fix grammar in active_record/counter_cache.rb [ci skip] 2017-01-02 11:41:40 +09:00
Kir Shatrov
6cd757963d Dump schema cache for custom connection
Today `rake db:schema:cache:dump` only supports dumping cache for a
single connection (`ActiveRecord::Base.connection`). This doesn't work
for apps with multiple databases.

This PR makes `DatabaseTasks` to provide an API for dumping schema cache
for any connection.
2017-01-01 19:23:23 -05:00
Ryuta Kamizono
a8b44e4f4e touch_time should be type casted to respect the precision of the column 2017-01-02 06:08:22 +09:00
Ryuta Kamizono
a685a865c6 Prefer each over map because unused return value 2017-01-02 05:02:48 +09:00
Ryuta Kamizono
04a120fd94 Don't invoke touch_updates if touch does not supplied
`touch_updates` calls `Time.now` via `current_time_from_proper_timezone`
so it is better to not invoke `touch_updates` if it is unnecessary.
2017-01-02 04:56:55 +09:00
Kasper Timm Hansen
19deeb08df Fix tests with counter cache touching and more.
* Refactor to use `touch_updates`

  Ensures we only call `current_time_from_proper_timezone` from one place.

* Clarify touch default in tests.

  Not interested in what happens when passed false but that
  nothing passed means no touching.

* Backdate touched columns in tests.

  We can't be sure a test progresses through time, so our
  touching code may be working correctly but the test
  itself is brittle.

  Fix by backdating that's further in the past akin to
  what the timestamps tests do:
  d753645d40/activerecord/test/cases/timestamp_test.rb (L17)

* Expand changelog entry.

  Elaborate and show examples.

Closes #26995.

[ Jarred Trost & Kasper Timm Hansen ]
2017-01-01 18:34:50 +01:00
Jarred Trost
bf77e641ce Added option to ActiveRecord::CounterCache methods. 2017-01-01 18:33:50 +01:00
Kasper Timm Hansen
e42cbb7d31 Revert "Merge pull request #27528 from kamipo/extract_casted_booleans"
As pointed out by @matthewd this change makes ImmutableString aware
of MysqlString's existence whereas previously MysqlString was only
overriding public API.

cc @kamipo

This reverts commit e632c2fa4cb60072a778ce95c952a0fa95e5b074, reversing
changes made to 334a7dcf107cd3ff1697163d331d289d6d65dcd7.
2017-01-01 14:34:04 +01:00
Ryuta Kamizono
2b5dacb43d Change timestamp_attributes_for_{create,update} from symbol to string
`timestamp_attributes_for_{create,update}` is defined as symbol but
always used as string with `to_s`. This allocates extra strings. To
avoid extra allocation, change the definitions from symbol to string.

```ruby
pp ObjectSpace::AllocationTracer.trace {
  1_000.times { |i|
    Post.create!
  }
}
```

Before:

```
["~/rails/activerecord/lib/active_record/timestamp.rb", 121]=>[1002, 0, 750, 0, 1, 18528],
["~/rails/activerecord/lib/active_record/timestamp.rb", 105]=>[1002, 0, 750, 0, 1, 7720],
["~/rails/activerecord/lib/active_record/timestamp.rb", 101]=>[1002, 0, 750, 0, 1, 7720],
["~/rails/activerecord/lib/active_record/timestamp.rb", 109]=>[1002, 0, 750, 0, 1, 13896],
["~/rails/activerecord/lib/active_record/timestamp.rb", 61]=>[4008, 0, 3000, 0, 1, 30880],
```

After:

```
["~/rails/activerecord/lib/active_record/timestamp.rb", 120]=>[1000, 0, 756, 0, 1, 17184],
["~/rails/activerecord/lib/active_record/timestamp.rb", 104]=>[1000, 0, 756, 0, 1, 7160],
["~/rails/activerecord/lib/active_record/timestamp.rb", 100]=>[1000, 0, 756, 0, 1, 7160],
["~/rails/activerecord/lib/active_record/timestamp.rb", 108]=>[1000, 0, 756, 0, 1, 12888],
```
2017-01-01 07:07:45 +09:00
Kasper Timm Hansen
e632c2fa4c Merge pull request #27528 from kamipo/extract_casted_booleans
Extract `casted_true`/`casted_false` for `Type::ImmutableString`
2016-12-31 21:54:20 +01:00
Ryuta Kamizono
6ba7adbaa7 Refactor CollectionAssociation#ids_reader
Simply we can do `target.pluck(reflection.association_primary_key)` if
`target` is loaded.
2017-01-01 04:33:59 +09:00
Ryuta Kamizono
d8e5751a1d Extract casted_true/casted_false for Type::ImmutableString
The only difference between `Type::ImmutableString` and its subclasses
is the representation of the casted booleans. Prefer extracting
`casted_true`/`casted_false` and override these by subclasses.
2017-01-01 04:01:17 +09:00