Có gì mới trong Rails 6.0?
Bài đăng này đã không được cập nhật trong 5 năm
- Trong phiên bản mới này, rails đã cải tiến nhiều về tốc độ và khả năng mở rộng.
- Chúng ta sẽ tìm hiểu qua xem chúng có những thay đổi gì mới nhé!
Active Record
- Thêm #delete_by và #destroy_by cho ActiveRecord::Relation methods
- Trước Rails 6, việc deleting/destroying bản ghi phù hợp với điều kiện đã cho được thực hiện như sau:
# Ví dụ để destroy all users phù hợp với điều kiện đã cho
User.find_by(email: "abc@example.com").destroy
User.where(email: "abc@example.com", status: 1).destroy_all
# Ví dụ để delete all users phù hợp với điều kiện đã cho
User.find_by(email: "abc@example.com").delete
User.where(email: "abc@example.com", status: 1).delete_all
- Trong Rails 6, các phương thức
delete_by
vàdestroy_by
mới đã được thêm vàoActiveRecord::Relation methods
.ActiveRecord::Relation#delete_by
là cách viết gọn cho câu lệnhrelation.where(conditions).delete_all
. Tương tự như vậy,ActiveRecord::Relation#destroy_by
là cách viết gọn cho câu lệnhrelation.where(conditions).destroy_all
. Ví dụ:
# Ví dụ để destroy all users phù hợp với điều kiện đã cho bằng cách sử dụng destroy_by
User.destroy_by(email: "abc@example.com")
User.destroy_by(email: "abc@example.com", status: 1)
# Ví dụ để delete all users phù hợp với điều kiện đã cho bằng cách sử dụng delete_by
User.delete_by(email: "abc@example.com")
User.delete_by(email: "abc@example.com", status: 1)
- Thêm #touch_all cho ActiveRecord::Relation methods
- Trước khi tìm hiểu về nó, chúng ta sẽ xem
touch method
là cái gì đã.#touch
được sử dụng để cập nhật trường update_at mặc định là cập nhật nó đến thời gian hiện tại. Nó cũng có thể dùng thời gian tùy chỉnh hoặc các cột khác nhau làm tham số. - Rails 6 đã thêm
#touch_all
trênActiveRecord :: Relation
đểtouch
vào nhiều bản ghi trong một lần (trước Rails 6, chúng ta cần lặp lại tất cả các bản ghi bằng cách sử dụng vòng lặp để đạt được điều này.) - Ví dụ trong Rails 5.2:
>> User.count
SELECT COUNT(\*) FROM "users"
=> 3
>> User.all.touch_all
=> Traceback (most recent call last):1: from (irb):2
NoMethodError (undefined method 'touch_all' for
#<User::ActiveRecord_Relation:0x00007fe6261f9c58>)
>> User.all.each(&:touch)
SELECT "users".* FROM "users"
begin transaction
UPDATE "users" SET "updated_at" = ? WHERE "users"."id" = ? [["updated_at", "2019-03-16 17:45:51.495203"], ["id", 1]]
commit transaction
begin transaction
UPDATE "users" SET "updated_at" = ? WHERE "users"."id" = ? [["updated_at", "2019-03-16 17:45:51.503415"], ["id", 2]]
commit transaction
begin transaction
UPDATE "users" SET "updated_at" = ? WHERE "users"."id" = ? [["updated_at", "2019-03-16 17:45:51.509058"], ["id", 3]]
commit transaction
=> [#<User id: 1, name: "ABC", created_at: "2019-03-16 16:09:29",
updated_at: "2019-03-16 17:45:51">, #<User id: 2, name: "IGH",
created_at: "2019-03-16 16:09:43", updated_at: "2019-03-16 17:45:51">,
#<User id: 3, name: "KOU", created_at: "2019-03-16 16:09:45",
updated_at: "2019-03-16 17:45:51">]
- Còn Rails 6.0.0.beta2:
>> User.count
SELECT COUNT(*) FROM "users"
=> 3
>> User.all.touch_all
UPDATE "users" SET "updated_at" = ? [["updated_at",
"2019-03-16 16:08:47.490507"]]
=> 3
#touch_all
trả về số lượng các bản ghi mà nó được gọi.
#touch_all
cũng nhận thời gian tùy chỉnh hoặc các cột khác nhau làm tham số.
- Trong Rails 6.0.0.beta2:
>> User.count
SELECT COUNT(*) FROM "users"
=> 3
>> User.all.touch_all(time: Time.new(2019, 3, 2, 1, 0, 0))
UPDATE "users" SET "updated_at" = ? [["updated_at", "2019-03-16 00:00:00"]]
=> 3
>> User.all.touch_all(:created_at)
UPDATE "users" SET "updated_at" = ?, "created_at" = ? [["updated_at",
"2019-03-16 17:55:41.828347"], ["created_at", "2019-03-16 17:55:41.828347"]]
=> 3
- Thêm ActiveRecord::Relation#pick
- Trước Rails 6, việc chọn giá trị đầu tiên từ một cột trong tập hợp các bản ghi khá là phức tạp. Ví dụ ta muốn lấy name đầu tiên trong tất cả các bài viết có thể loại là 1:
>> Post.where(category: 1).limit(1).pluck(:name).first
SELECT "posts"."name"
FROM "posts"
WHERE "posts"."category" = ?
LIMIT ? [["category", 1], ["LIMIT", 1]]
=> "Hello!"
- Trong Rails 6, phương thức
ActiveRecord::Relation#pick
mới đã được thêm vào làm tối giản đi cách viết để chọn ra giá trị đầu tiên.
>> Post.where(category: 1).pick(:name, :author)
SELECT "posts"."name", "posts"."author"
FROM "posts"
WHERE "posts"."category" = ?
LIMIT ? [["category", 1], ["LIMIT", 1]]
=> ["Hello", "VN"]
- Thêm negative scopes cho enum
- Khi một thuộc tính enum được định nghĩa trên model, Rails thêm một số default scope để lọc các bản ghi dựa trên các giá trị của enum trên trường enum.
- Ví dụ:
class Post < ActiveRecord::Base
enum status: %i[drafted active trashed]
end
Post.drafted # => where(status: :drafted)
Post.active # => where(status: :active)
- Trong Rails 6, negative scope được thêm vào các giá trị enum.
- Ví dụ:
class Post < ActiveRecord::Base
enum status: %i[drafted active trashed]
end
Post.not_drafted # => where.not(status: :drafted)
Post.not_active # => where.not(status: :active)
- Ngoài ra, rails 6 còn thêm basic API dùng cho việc chuyển đổi kết nối để hỗ trợ nhiều cơ sở dữ liệu khác nhau
Action Mailbox
- Action Mailbox được giới thiệu trong ver 6 của Rails, Action Mailbox cung cấp một bộ công cụ cho phép các ứng dụng tích hợp tốt hơn với các luồng email gửi đến (những điều cơ bản về cách setup nó được trình bày trong Action Mailbox Basics Rails Guide )
- Các bạn có thể tìm hiểu thêm về nó tại đây set up Action Mailbox.
Action View
- Rails 6 sẽ báo cáo về các phân bổ được thực hiện trong các khung nhìn, điều này sẽ cho phép ta nhìn thấy được việc dành bao nhiêu thời gian để phân bổ và thu gom các đối tượng trong bộ nhớ xử lý.
Rendered posts/_form.html.erb (Duration: 7.1ms | Allocations: 6004)
Rendered posts/new.html.erb within layouts/application
(Duration: 8.3ms | Allocations: 6654)
Completed 200 OK in 858ms (Views: 848.4ms | ActiveRecord: 0.4ms
| Allocations: 1539564)
Active Model
- Cho phép tên thuộc tính có thể định cấu hình cho #has_secure_password.
- Điều này vẫn mặc định cho thuộc tính có tên là 'password'. Trong ver mới này, có một phương thức mới mang tên
#authenticate_XXX
, trong đó XXX là tên thuộc tính được xác định để cấu hình, có thể coi #authenticate hiện tại thành bí danh khi thuộc tính là 'password' mặc định.
class User < ActiveRecord::Base
has_secure_password :recovery_password, validations: false
end
user = User.new()
user.recovery_password = "42password"
user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uX..."
user.authenticate_recovery_password('42password') # => user
Tài liệu tham khảo
All rights reserved