- 17 7月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
This reverts commit b8064500, reversing changes made to 8714b359. Reason: This is not approved from the core team yet...
-
- 14 7月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
```ruby class Post < ActiveRecord::Base attribute :written_at, default: -> { Time.now.utc } end # Rails 6.0 Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...> # Rails 6.1 Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...> ``` This is an alternative of #39797. Context https://github.com/rails/rails/pull/39797#issuecomment-655191817. If people intend to override the existing type on the attribute, usually an overriding type is explicitly specified, so I agree that the current behavior (drop existing type information if type is omitted) is practically quite useless, and it is almost like a bug in that there is no way to override just the default. So I'd like to change the current behavior on existing attributes without a deprecation as a fix. Closes #39797. See also https://github.com/kufu/activerecord-bitemporal/pull/57.
-
- 10 7月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
```ruby class Book < ActiveRecord::Base enum status: [:proposed, :written, :published], _default: :published end Book.new.status # => "published" ```
-
- 07 7月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
-
- 06 7月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
```ruby posts = Post.order(:id) posts.where("id >": 9).pluck(:id) # => [10, 11] posts.where("id >=": 9).pluck(:id) # => [9, 10, 11] posts.where("id <": 3).pluck(:id) # => [1, 2] posts.where("id <=": 3).pluck(:id) # => [1, 2, 3] ``` From type casting and table/column name resolution's point of view, `where("create_at >=": time)` is better alternative than `where("create_at >= ?", time)`. ```ruby class Post < ActiveRecord::Base attribute :created_at, :datetime, precision: 3 end time = Time.now.utc # => 2020-06-24 10:11:12.123456 UTC Post.create!(created_at: time) # => #<Post id: 1, created_at: "2020-06-24 10:11:12.123000"> # SELECT `posts`.* FROM `posts` WHERE (created_at >= '2020-06-24 10:11:12.123456') Post.where("created_at >= ?", time) # => [] # SELECT `posts`.* FROM `posts` WHERE `posts`.`created_at` >= '2020-06-24 10:11:12.123000' Post.where("created_at >=": time) # => [#<Post id: 1, created_at: "2020-06-24 10:11:12.123000">] ```
-
- 15 6月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
`LegacyYamlAdapter` was added at afc124c3 (and 4e721702), to be able to load the previous version formatted YAML. Now, that has became quite useless, since we sometimes removed/added dedicated type classes which are referred in the legacy format (e.g. `MysqlDateTime`, `MysqlString`, `SQLite3Integer`), so it is unlikely that is able to load it correctly any longer.
-
- 11 6月, 2020 1 次提交
-
-
由 Sean Griffin 提交于
In Rails 4.2 we introduced mutation detection, to remove the need to call `attribute_will_change!` after modifying a field. One side effect of that change was that we needed to enforce that the `_before_type_cast` form of a value is a different object than the post type cast value, if the value is mutable. That contract is really only relevant for strings, but it meant we needed to dup them. In Rails 5 we added the `ImmutableString` type, to allow people to opt out of this duping in places where the memory usage was causing problems, and they don't need to mutate that field. This takes that a step further, and adds a class-level setting to specify whether strings should be frozen by default or not. The default value of this setting is `false` (strings are mutable), and I do not plan on changing that. While I think that immutable strings by default would be a reasonable default for new applications, I do not think that we would be able to document the value of this setting in a place that people will be looking when they can't figure out why some string is frozen. Realistically, the number of applications where this setting is relevant is fairly small, so I don't think it would make sense to ever enable it by default.
-
- 10 6月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
These actually does not inplace mutate result. Use true `map` instead.
-
- 07 6月, 2020 3 次提交
-
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
As described at #39328, `relation.merge` behaves inspired as Hash-like merge for where clause. In other words, currently there is no official way to intersect the result by both relation conditions (i.e. there is no official way to maintain both relation conditions). To resolve that issue, I'd like to support a way to intersect relations as `relation.and`. ```ruby david_and_mary = Author.where(id: [david, mary]) mary_and_bob = Author.where(id: [mary, bob]) # => [bob] david_and_mary.merge(mary_and_bob) # => [mary, bob] david_and_mary.and(mary_and_bob) # => [mary] david_and_mary.or(mary_and_bob) # => [david, mary, bob] ``` Fixes #39232.
-
由 Ryuta Kamizono 提交于
Related to #39250 and #39236. The purpose of the change here is to unify inconsistent behavior on the merging. For now, mergee side condition is replaced by merger side condition only if both arel nodes are Equality or In clauses. In other words, if mergee side condition is not Equality or In clauses (e.g. `between`, `or`, `gt`, `lt`, etc), those conditions will be kept even on the same column. This behavior is harder to predict unless people are familiar with the merging behavior. Originally I suppose this behavior is just an implementation issue rather than an intended one, since `unscope` and `rewhere`, which were introduced later than `merge`, works more consistently. Since most of the conditions are usually Equality and In clauses, I don't suppose most people have encountered this merging issue, but I'd like to deprecate the inconsistent behavior and will completely unify that to improve a future UX. ```ruby # Rails 6.1 (IN clause is replaced by merger side equality condition) Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob] # Rails 6.1 (both conflict conditions exists, deprecated) Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [] # Rails 6.1 with rewhere to migrate to Rails 6.2's behavior Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob] # Rails 6.2 (same behavior with IN clause, mergee side condition is consistently replaced) Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob] Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob] ```
-
- 04 6月, 2020 1 次提交
-
-
由 Peter Fry 提交于
Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case. Fix Rubocop warnings. Fix merge conflict error. Fix merge conflict error.
-
- 03 6月, 2020 2 次提交
-
-
由 Austen Madden 提交于
Based on the docs which state unique_by option of insert_all can use the index name if desired, one would expect the method to work normally and use the `unique_by` option to determine duplicates. However, there's an issue where the insert_all expects a Set instead of the string representing the index expression it is given. This causes an error. Returning the string expression instead of attempting to format it works perfectly though.
-
由 fatkodima 提交于
-
- 01 6月, 2020 1 次提交
-
-
由 bogdanvlviv 提交于
Add `ActiveRecord::Base.strict_loading_by_default` and `ActiveRecord::Base.strict_loading_by_default=`. This will allow to enable/disable strict_loading mode by default for a model. The configuration's value is inheritable by subclasses, but they can override that value and it will not impact parent class: ```ruby class Developer < ApplicationRecord self.strict_loading_by_default = true has_many :projects end dev = Developer.first dev.projects.first \# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded. ``` What is great about this feature that it could help users to nip N+1 queries in the bud, especially for fresh applications, by setting `ActiveRecord::Base.strict_loading_by_default = true` / `config.active_record.strict_loading_by_default = true`. That is also a great way to prevent new N+1 queries in the existing applications after all the N+1 queries are eliminated. (See https://guides.rubyonrails.org/v6.0/active_record_querying.html#eager-loading-associations, https://github.com/seejohnrun/prelude for details on how to fight against N+1 queries). Related to https://github.com/rails/rails/pull/37400, https://github.com/rails/rails/pull/38541
-
- 31 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
Follow up to #27962. #27962 only deprecated `quoted_id`, but still conservatively allowed passing an Active Record object. Since the quoting methods on a `connection` are low-level API and querying API does not rely on that ability, so people should pass casted value instead of an Active Record object if using the quoting methods directly.
-
- 28 5月, 2020 1 次提交
-
-
由 Dylan Thacker-Smith 提交于
It doesn't matter if the transaction is rolled back or committed if it wasn't written to, so we can avoid warning about a breaking change.
-
- 24 5月, 2020 3 次提交
-
-
由 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.
-
由 David Heinemeier Hansson 提交于
-
由 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 # } ```
-
- 20 5月, 2020 1 次提交
-
-
由 Aaron Lipman 提交于
Bump an Active Record instance's lock version after updating its counter cache. This avoids raising an unnecessary ActiveRecord::StaleObjectError upon subsequent transactions by maintaining parity with the corresponding database record's lock_version column.
-
- 18 5月, 2020 3 次提交
-
-
由 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] ```
-
由 Ryuta Kamizono 提交于
-
由 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.
-
- 13 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
This is the opposite direction of #39039. #39111 fixes `minimum` and `maximum` on date columns with type casting by column type on the database. But column type has no information for time zone aware attributes, it means that attribute type should always be precedence over column type. I've realized that fact in the related issue report #39248. I've reverted the expectation of #39039, to make time zone aware attributes works.
-
- 10 5月, 2020 2 次提交
-
-
由 Ryuta Kamizono 提交于
Since MySQL 8.0.12, MySQL supports `ALGORITHM=INSTANT` DDL option. https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-operations
-
由 Ryuta Kamizono 提交于
I've found the bug when I'm refactoring index creation code in #39203.
-
- 07 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
It is possible to unscope only the column in the specified table. ```ruby posts = Post.joins(:comments).group(:"posts.hidden") posts = posts.where("posts.hidden": false, "comments.hidden": false) posts.count # => { false => 10 } # unscope both hidden columns posts.unscope(where: :hidden).count # => { false => 11, true => 1 } # unscope only comments.hidden column posts.unscope(where: :"comments.hidden").count # => { false => 11 } ``` Co-authored-by: NSlava Korolev <korolvs@gmail.com>
-
- 05 5月, 2020 2 次提交
-
-
由 Ryuta Kamizono 提交于
```ruby steve = Person.find_by(name: "Steve") david = Author.find_by(name: "David") relation = Essay.where(writer: steve) # Before relation.rewhere(writer: david).to_a # => [] # After relation.rewhere(writer: david).to_a # => [david] ``` For now `rewhere` only works for truly column names, doesn't work for alias attributes, nested conditions, associations. To fix that, need to build new where clause first, and then get attribute names from new where clause.
-
由 akinomaeni 提交于
before ``` p Knot.create => #<Knot id: 1, created_at: "2016-05-05 01:29:47"> ``` after ``` p Knot.create => #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000"> ```
-
- 02 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
The type information for type casting is entirely separated to type object, so if anyone does passing a column to `type_cast` in Rails 6, they are likely doing something wrong. See the comment for more details: https://github.com/rails/rails/blob/28d815b89487ce4001a3f6f0ab684e6f9c017ed0/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb#L33-L42 This also deprecates passing legacy binds (an array of `[column, value]` which is 4.2 style format) to query methods on connection. That legacy format was kept for backward compatibility, instead of that, I've supported casted binds format (an array of casted values), it is easier to construct binds than existing two binds format.
-
- 30 4月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
`allowed_index_name_length` was used for internal temporary operations in SQLite3, since index name in SQLite3 must be globally unique and SQLite3 doesn't have ALTER TABLE feature (so it is emulated by creating temporary table with prefix). `allowed_index_name_length` was to reserve the margin for the prefix, but actually SQLite3 doesn't have a limitation for identifier name length, so the margin has removed at 36901e6e. Now `allowed_index_name_length` is no longer relied on by any adapter, so I'd like to remove the internal specific method which is no longer used.
-
- 27 4月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
`in_clause_length` was added at c5a284f8 to address to Oracle IN clause length limitation. Now `in_clause_length` is entirely integrated in Arel visitor since #35838 and #36074. Since Oracle visitors are the only code that rely on `in_clause_length`. so I'd like to remove that from Rails code base, like has removed Oracle visitors (#38946).
-
- 25 4月, 2020 2 次提交
-
-
由 Ryuta Kamizono 提交于
Currently, `count` and `average` always returns numeric value, but `sum`, `maximum`, and `minimum` not always return numeric value if aggregated on custom attribute type. I think that inconsistent behavior is surprising: ```ruby # All adapters except postgresql adapter are affected # by custom type casting. Book.group(:status).sum(:status) # => { "proposed" => "proposed", "published" => nil } ``` That is caused by fallback looking up cast type to `type_for(column)`. Now all supported adapters can return numeric value without that fallback, so I think we can remove that, it will also fix aggregate functions to return numeric value consistently.
-
由 Ryuta Kamizono 提交于
This allows to work `author.books.insert_all` as expected. Co-authored-by: NJosef Šimánek <josef.simanek@gmail.com>
-
- 20 4月, 2020 1 次提交
-
-
由 Islam Taha 提交于
Update activerecord changelog Specify DB name in changelog and fix typo
-
- 16 4月, 2020 1 次提交
-
-
由 eileencodes 提交于
This PR allows for passing `if_exists` options to the `remove_index` method so that we can ignore already removed indexes. This work follows column `if/if_not_exists` from #38352 and `:if_not_exists` on `add_index` from #38555. We've found this useful at GitHub, there are migrations where we don't want to raise if an index was already removed. This will allow us to remove a monkey patch on `remove_index`. I considered raising after the `index_name_for_remove` method is called but that method will raise if the index doesn't exist before we get to execute. I have a commit that refactors this but after much consideration this change is cleaner and more straightforward than other ways of implementing this. This change also adds a little extra validation to the `add_index` test. Fix `nodoc` on edited methods.
-
- 15 4月, 2020 2 次提交
-
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
This removes ibm_db, informix, mssql, oracle, and oracle12 Arel visitors which are not used in the code base. Actually oracle and oracle12 visitors are used at oracle-enhanced adapter, but now I think that those visitors should be in the adapter's repo like sqlserver adapter and the dedicated Arel visitor (https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/arel/visitors/sqlserver.rb), otherwise it is hard to find a bug and review PRs for the oracle visitors (e.g. #35838, #37646), since we don't have knowledge and environment enough for Oracle.
-
- 14 4月, 2020 1 次提交
-
-
由 Josh 提交于
Previously, if `build_association` was called multiple times for a `has_one` association but never committed to the database, the first newly-associated record would trigger `touch` during the attempted removal of the record. For example: class Post < ActiveRecord::Base has_one :comment, inverse_of: :post, dependent: :destroy end class Comment < ActiveRecord::Base belongs_to :post, inverse_of: :comment, touch: true end post = Post.create! comment_1 = post.build_comment comment_2 = post.build_comment When `comment_2` is initialized, the `has_one` would attempt to destroy `comment_1`, triggering a `touch` on `post` from an association record that hasn't been committed to the database. This removes the attempt to delete an associated `has_one` unless it’s persisted.
-