Length, Size, and Count in Ruby and Rails: Khi nào nên sử dụng chúng?

Tương tự Ruby thì trong Rails cung cấp cho chúng ta nhiều cách để làm một hành động tương tự nhau. Ví dụ rõ ràng nhất là bài toán tìm số phần tử trong một Collection. Bạn có thể sử dụng các method length, sizecount để thực hiện việc này.

Tuy nhiên, bạn cảm thấy khó hiểu vì sao lại có tận 3 method và chúng khác nhau như thế nào? Khi nào nên sử dụng chúng hoặc lựa chọn chúng có ảnh hưởng đến performance của dự án hay không? Bài đăng này sẽ khám phá sự khác biệt của chúng.

Hãy bắt đầu với cái nhìn tổng quan về các phương thức này trong Array của Ruby. Sau đó chúng ta sẽ chuyển sang Rails.

Ruby

1. Length

Đây là phương thức đơn giản nhất và thân thuộc nhất trong 3 loại. Bạn có thể thấy chúng trong bất kì dự án nào bạn làm.

Method length nó trả về số lượng phần tử trong một mảng.

Cú pháp rất đơn giản phải không nào?

Ruby
numbers = [1,2,3,4,5,6]

numbers.length # => 6

2. Size

Size thực chất là alias của length. Cách nó thực thi giống như length vậy.

Ruby
rubynumbers = [1,2,3,4,5,6]

numbers.size # => 6

Vậy thì khi nào sẽ sử dụng lengthsize? Đó là sử dụng tuỳ theo ngữ cảnh mà bạn đang gặp phải.

Ví dụ: Nếu tôi có một mảng class_room chứa một nhóm các học sinh, tôi sẽ sử dụng class_room.size thay vì class_room.length. Mặc khác, nếu tôi sử lý một mảng các numbers, tôi sẽ sử dụng method length.

3. Count

Phương thức này thường được sử dụng để đếm số phần tử được chỉ định trong Array. Sử dụng chúng khi bạn cần tìm một phần tử phù hợp với một tiêu chí nào đó. Có 4 trường hợp sử dụng phương pháp này.

3.1 Nếu như không có argument và không có block, trả về số lượng tất cả các phần tử

Ruby
[10, 20, 30].count # => 3

[].count # => 0


3.2 Khi có argument, trả về argument được cung cấp

Ruby
[0, 5, 10, 0.0].count(0) # => 2

[0, 1, 2].count(3) # => 0


3.3 Khi có block nhưng lại không có argument

Ruby
[0, 5, 10, 15].count { |e| e > 5 } # => 2


3.4 Nếu vừa có cả block và argument, nó bỏ qua block và trả về các đối số thoả điều kiện

Ruby
[0, 1, 2, 3].count(2) { |e| e = 0 } # => 1

Nhưng phương thức này sẽ trả ra một WARNING như bên dưới:

Ruby On Rails

Chúng ta sẽ lấy ví dụ từ lớp ActiveRecord::Associations::CollectionProxy được kế thừa từ lớp ActiveRecord::Relation.

Ruby
class Company < ActiveRecord::Base
  has_many :company_members
end

company = Company.first
company_members = company.company_members

# CompanyMember::ActiveRecord_Associations_CollectionProxy
company_members.class 

Ở ví dụ trên, comments là một Collection Proxy, bây giờ hãy tìm hiểu cách các phương thức này hoạt động trên Collection Proxy.

1. Size

Nếu collection chưa được query, thì phương thức size sẽ thực thi câu lệnh SELECT COUNT(*). Ngược lại thì chúng sẽ gọi collection.size

Ruby
Company.all.size
# SELECT "companies".* FROM "companies"

2. Length

Trả về size cua Collection bằng cách call method size.

Ruby
Company.all.length
# SELECT "companies".* FROM "companies"

Điều đó có nghĩa thì nếu collection đã được loaded thì method sizelength tương đương nhau

Vậy khi nào nên dùng size vs length?

Khi Collection đã được loaded thì method size và length đều như nhau.

Còn nếu collection không được load từ database:

  • Nếu bạn cần vẫn cần records bất cứ lúc nào thì hãy sử dụng method length. Điều này sẽ giảm đi một truy vấn, vì Rails sẽ sử dụng các bản ghi được lưu trong bộ nhớ cache cho truy vấn sau đó.
  • Nếu bạn không cần records thì sử dụng method size sẽ hiệu quả hơn. Method này sẽ thực hiện một truy vấn COUNT SQL để lấy số lượng trực tiếp từ cơ sở dữ liệu, mà không cần tải các bản ghi vào bộ nhớ.

3. Count

Tương tự như method count của Ruby, method count trong Rails đếm tất cả các bản ghi trong một tập hợp thỏa mãn một điều kiện cho trước. Có 2 trường hợp sử dụng:

  • Khi không có block, trả về số lượng tất cả records trong table
Ruby
companies = Company.all

# SELECT COUNT(*) FROM "companies"
companies.count
  • Khi có block, method count trong Rails gọi block với mỗi phần tử trong tập hợp và trả về số lượng phần tử mà khối trả về giá trị đúng (truthy).
Ruby
Company.all.count { |company| company.charge_firstname.include?('Be') }

KẾT

Hy vọng rằng bạn đã thấy bài viết này hữu ích và bạn đã học được điều gì đó mới. 😀

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Cài đặt Rails 7 với Vite + Stimulus + Tailwind
Read More

Cài đặt Rails 7 với Vite + Stimulus + Tailwind

Nếu bạn đang tìm kiếm một giải pháp phát triển web hiệu suất cao và tiện lợi, Vite sẽ là lựa chọn đáng xem xét. Còn với Rails 7, bạn sẽ phải cân nhắc xem tính năng importmap có đủ thuyết phục để bạn chuyển đổi không.
Read More

Setup slack notifications in Rails

Table of Contents Hide Setup Slack:Setup Rails: Slack là một phần mềm Worksplace sử dụng thông dụng rộng…