1. 24 5月, 2020 7 次提交
    • R
      Separate primary key column options from table options · 859681ec
      Ryuta Kamizono 提交于
      Otherwise we cannot handle the same name options for both column and
      table (e.g. `:comment`, `:charset`, `:collation`).
      859681ec
    • R
      Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic · 3c6be5e5
      Ryuta Kamizono 提交于
      5 years ago, I made dumping full table options at #17569, especially to
      dump `ENGINE=InnoDB ROW_FORMAT=DYNAMIC` to use utf8mb4 with large key
      prefix.
      
      In that time, omitting the default engine `ENGINE=InnoDB` was not useful
      since `ROW_FORMAT=DYNAMIC` always remains as long as using utf8mb4 with
      large key prefix.
      
      But now, MySQL 5.7.9 has finally changed the default row format to
      DYNAMIC, utf8mb4 with large key prefix can be used without dumping the
      default engine and the row format explicitly.
      
      So now is a good time to make the default engine is omitted.
      
      Before:
      
      ```ruby
      create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
      end
      ```
      
      After:
      
      ```ruby
      create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
      end
      ```
      
      To entirely omit `:options` option to make schema agnostic, I've added
      `:charset` and `:collation` table options to exclude `CHARSET` and
      `COLLATE` from `:options`.
      
      Fixes #26209.
      Closes #29472.
      
      See also #33608, #33853, and #34742.
      3c6be5e5
    • D
      fd8fd4ae
    • P
      277d6372
    • R
      Remove redundant `blank?` check and `compact_blank!` for `joins_values` · 068a436f
      Ryuta Kamizono 提交于
      `joins_values` is already `compact_blank!`ed, so `blank?` check is
      entirely redundant.
      068a436f
    • R
      Deprecate aggregations with group by duplicated fields · 2580b83f
      Ryuta Kamizono 提交于
      We've learned that `merge` causes duplicated multiple values easily, so
      if we missed to deduplicate the values, it will cause weird behavior
      like #38052, #39171.
      
      I've investigated the deduplication for the values, at least that had
      existed since Rails 3.0.
      
      https://github.com/rails/rails/commit/bed9179aa1496f6d28891cf515af0d7e515ebbab
      
      Aggregations with group by multiple fields was introduced at Rails 3.1,
      but we missed the deduplication for the aggregation result, unlike the
      generated SQL.
      
      https://github.com/rails/rails/commit/a5cdf0b9eb860c4370ae5fde231e1b61f71b6b65
      
      While the investigation, I've found that `annotate` is also missed the
      deduplication.
      
      I don't suppose this weird behavior is intended for both.
      
      So I'd like to deprecate the duplicated behavior in Rails 6.1, and will
      be deduplicated all multiple values in Rails 6.2.
      
      To migrate to Rails 6.2's behavior, use `uniq!(:group)` to deduplicate
      group fields.
      
      ```ruby
      accounts = Account.group(:firm_id)
      
      # duplicated group fields, deprecated.
      accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
      # => {
      #   [1, 1] => 50,
      #   [2, 2] => 60
      # }
      
      # use `uniq!(:group)` to deduplicate group fields.
      accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
      # => {
      #   1 => 50,
      #   2 => 60
      # }
      ```
      2580b83f
    • R
      Deduplicate same clauses in `merge` · 5528a79d
      Ryuta Kamizono 提交于
      Related to #39328, #39358.
      
      For now, `merge` cannot override non-equality clauses, so non-equality
      clauses will easily be duplicated by `merge`.
      
      This deduplicates redundant same clauses in `merge`.
      5528a79d
  2. 22 5月, 2020 1 次提交
  3. 21 5月, 2020 2 次提交
  4. 20 5月, 2020 5 次提交
  5. 19 5月, 2020 3 次提交
    • P
      Add DidYouMean for HasManyThroughAssociationNotFoundError · 9082364a
      Petrik 提交于
      If a has_many :through association isn't found we can suggest similar associations:
      
      ```
      class Author
        has_many :categorizations, -> { }
        has_many :categories, through: :categorizations
        has_many :categorized_posts, through: :categorizations, source: :post
        has_many :category_post_comments, through: :categories, source: :post_comments
      
        has_many :nothings, through: :kateggorisatons, class_name: "Category"
      end
      
      Author.first.nothings
      
      Could not find the association :kateggorisatons in model Author
      Did you mean?  categorizations
                     categories
                     categorized_posts
                     category_post_comments
      ```
      9082364a
    • R
      Test multiple values with blank value · 4774fa0d
      Ryuta Kamizono 提交于
      4774fa0d
    • R
      Unify the query values normalization for multiple values · 60387553
      Ryuta Kamizono 提交于
      Currently the query values normalization for multiple values is missing
      some parts.
      
      Some values are flatten, but others are not flatten.
      Some values are compact, but others are not compact.
      some values are compact_blank, but others are not compact_blank.
      
      Originally all multiple values should be flatten and compact_blank
      before `build_arel`, if it is not ensured which multiple values are
      normalized or not, we need to normalize it again carefully and
      conservatively in `build_arel`.
      
      To unify the query values normalization for multiple values, ensure the
      normalization in `check_if_method_has_arguments!` since all multiple
      values should be checked by the method.
      60387553
  6. 18 5月, 2020 8 次提交
    • R
      Support merging option `:rewhere` to allow mergee side condition to be replaced exactly · f6fb3271
      Ryuta Kamizono 提交于
      Related #39236.
      
      `relation.merge` method sometimes replaces mergee side condition, but
      sometimes maintain both conditions unless `relation.rewhere` is used.
      
      It is very hard to predict merging result whether mergee side condition
      will be replaced or not.
      
      One existing way is to use `relation.rewhere` for merger side relation,
      but it is also hard to predict a relation will be used for `merge` in
      advance, except one-time relation for `merge`.
      
      To address that issue, I propose to support merging option `:rewhere`,
      to allow mergee side condition to be replaced exactly.
      
      That option will allow non-`rewhere` relation behaves as `rewhere`d
      relation.
      
      ```ruby
      david_and_mary = Author.where(id: david.id..mary.id)
      
      # both conflict conditions exists
      david_and_mary.merge(Author.where(id: bob)) # => []
      
      # mergee side condition is replaced by rewhere
      david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
      
      # mergee side condition is replaced by rewhere option
      david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
      ```
      f6fb3271
    • R
      Fix rename column in bulk alter table for PostgreSQL · 6bd2bb75
      Ryuta Kamizono 提交于
      PostgreSQL doesn't support rename column operation in bulk alter table.
      
      Fixes #39322.
      6bd2bb75
    • R
      Fix update with dirty locking column to not match latest object accidentally · fba016c7
      Ryuta Kamizono 提交于
      Related #32163.
      
      We should not identify an object by dirty value. If do so, accidentally
      matches latest object even though it is a stale object.
      fba016c7
    • F
    • P
      Use DidYouMean for AssociationNotFoundError · 3bc77560
      Petrik 提交于
      If an association isn't found we can suggest matching associations:
      
      ```
      Post.all.merge!(includes: :monkeys).find(6)
      
      Association named 'monkeys' was not found on Post; perhaps you misspelled it?
      Did you mean?  funky_tags
                     comments
                     images
                     skimmers
      ```
      3bc77560
    • R
      Remove redundant looking type up from explicit `klass.attribute_types` · b0d0feab
      Ryuta Kamizono 提交于
      In aggregation value's type cast, `klass.attribute_types.fetch(...)`
      will find no type almost all cases, since any type is already returned
      by `column.type_caster` in that case.
      And also, the root of join dependency tree is also the model's `klass`,
      so the explicit `klass.attribute_types` is redundant originally.
      b0d0feab
    • D
      Add signed ids to Active Record (#39313) · 1a3dc42c
      David Heinemeier Hansson 提交于
      Add support for finding records based on signed ids, which are tamper-proof, verified ids that can be set to expire and scoped with a purpose. This is particularly useful for things like password reset or email verification, where you want the bearer of the signed id to be able to interact with the underlying record, but usually only within a certain time period.
      1a3dc42c
    • R
      Clear `@_defer_touch_attrs` when it has used · e7c0cc85
      Ryuta Kamizono 提交于
      Otherwise `@_defer_touch_attrs` is touched again with old `@_touch_time`
      in `before_committed!`.
      e7c0cc85
  7. 17 5月, 2020 3 次提交
  8. 16 5月, 2020 1 次提交
    • R
      Fix eager load with Arel joins to maintain the original joins order · 8f365c5d
      Ryuta Kamizono 提交于
      #38354 is caused by #36304, to fix invalid joins order for through
      associations.
      
      Actually passing Arel joins to `joins` is not officially supported
      unlike string joins, and also Arel joins could be easily converted to
      string joins by `to_sql`. But I'd not intend to break existing apps
      without deprecation cycle, so I've changed to mark only implicit joins
      as leading joins, to maintain the original joins order for user supplied
      Arel joins.
      
      Fixes #38354.
      8f365c5d
  9. 15 5月, 2020 5 次提交
  10. 14 5月, 2020 4 次提交
  11. 13 5月, 2020 1 次提交
    • R
      Improve performance for loaded association's `first` · c2a3fdc0
      Ryuta Kamizono 提交于
      Delegate to scope values (e.g. `offset_value`, `order_values`) is slow.
      
      We can avoid that if records are already loaded.
      
      ```ruby
      class Post < ActiveRecord::Base
        has_many :comments
      end
      
      class Comment < ActiveRecord::Base
        belongs_to :post
        has_many :likes
      end
      
      class Like < ActiveRecord::Base
        belongs_to :post
      end
      
      10.times { Post.create! }
      30.times { |i| Comment.create!(post_id: 1 + i % 10) }
      150.times { |i |Like.create!(comment_id: 1 + i % 30) }
      
      post = Post.includes(comments: :likes).last
      
      result = Benchmark.measure do
        100.times { post.comments.each { |c| c.likes.first.id } }
      end
      
      puts
      puts result
      ```
      
      Before:
      
      ```
        0.013542   0.000582   0.014124 (  0.014125)
      ```
      
      After:
      
      ```
        0.000938   0.000017   0.000955 (  0.000952)
      ```
      
      Fixes #38252.
      c2a3fdc0