Bạn có một vài tùy chọn khác nhau cho bỏ qua một bản cập nhật của bộ nhớ cache truy cập, và một trong đó bạn chọn thực sự phụ thuộc vào cách bạn muốn cấu trúc ứng dụng của mình. Tôi sẽ thảo luận về những cách khác nhau mà bạn có thể nhận được xung quanh bộ nhớ cache truy cập và đề cập đến một số trong những cân nhắc bạn có thể muốn thực hiện khi làm như vậy.
Về cơ bản, có ba cách khác nhau mà bạn có thể bỏ qua các bản cập nhật của bộ nhớ cache truy cập:
- Monkey patch your model to disable the counter cache callback
- Use an update method that doesn't trigger callbacks
- Xác định một mô hình trỏ thay thế cho cùng một bảng mà không có cùng một hành vi gọi lại và sử dụng hành vi đó khi chèn hàng loạt vào cơ sở dữ liệu
Lưu ý rằng hai tùy chọn đầu tiên ở trên là g liên quan đến việc vô hiệu hóa các cuộc gọi lại trong ActiveRecord và điều này có ý nghĩa vì bộ đệm truy cập được thực hiện nội bộ bằng phương thức gọi lại.
Khi Rails tải một mô hình có các liên kết với bộ đệm truy cập, nó định nghĩa động các phương thức gọi lại. Nếu bạn muốn vô hiệu hóa chúng như một cuộc gọi lại, trước tiên bạn phải tìm ra tên gọi lại là gì.
Có hai cách chính để tìm ra phương pháp mà Rails đã xác định để thực hiện các cuộc gọi lại này. Bạn có thể đọc nguồn Rails để tìm ra các tên mà nó sẽ tạo ra thông qua sự tích hợp chuỗi, hoặc bạn có thể sử dụng nội tâm để tìm ra phương thức mà lớp của bạn đáp ứng. Tôi sẽ đưa ra một ví dụ về cách bạn có thể sử dụng nội tâm để tìm ra các callback được định nghĩa bởi ActiveRecord để tự động thực hiện bộ nhớ đệm truy cập.
Giả sử bạn có một lớp được gọi là SpecialReply xuống từ lớp Trả lời xuống từ ActiveRecord :: Base (this example comes from the test suite with Rails). Nó có có một cột truy cập bộ nhớ cache theo quy định dưới đây:
class SpecialReply < ::Reply
belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
end
Trong giao diện điều khiển, bạn có thể xem những gì các phương pháp lớp học của bạn đáp lại bằng cách sử dụng .methods
. Điều này sẽ tạo ra rất nhiều tiếng ồn, vì mỗi thể hiện của Object
đã đáp ứng rất nhiều phương pháp, vì vậy bạn có thể thu hẹp danh sách như sau:
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods - Object.methods
Trên dòng thứ hai bạn đang nói, show tôi tất cả các phương pháp mà trường hợp của tôi SpecialReply phản ứng, trừ đi những đối tượng mà tất cả các đối tượng phản hồi. Điều này thường giúp ích cho việc tìm kiếm bằng cách lọc ra các phương thức không dành riêng cho loại lớp mà bạn đang xem.
Thật không may ngay cả sau khi bộ lọc này có nhiều tiếng ồn do các phương thức mà ActiveRecord thêm vào tất cả các lớp con cháu của nó. Trong trường hợp này grep
rất hữu ích - kể từ ActiveRecord helpfully tạo ra các phương thức callback truy cập có chứa String counter_cache
(see the meta-programming used by ActiveRecord to generate a counter cache method for a belongs_to
association), bạn có thể tìm hiểu các callbacks được xác định liên quan để đối phó với bộ nhớ đệm như sau:
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods.map(&:to_s).grep(/counter_cache/)
Chú ý rằng kể từ khi grep
hoạt động trên một String, và methods
trả về một mảng các tên phương thức biểu tượng, trước tiên chúng ta sử dụng to_proc
(&:
) để chuyển đổi tất cả các ký hiệu thành chuỗi và sau đó grep ra các ký tự có chứa counter_cache
. Điều này khiến tôi với các phương pháp sau đây mà dường như họ có lẽ tính năng tự động tạo ra bởi ActiveRecord như callbacks để thực hiện truy cập bộ nhớ đệm:
belongs_to_counter_cache_after_create_for_special_topic
belongs_to_counter_cache_before_destroy_for_special_topic
belongs_to_counter_cache_after_create_for_topic
belongs_to_counter_cache_before_destroy_for_topic
belongs_to_counter_cache_after_create_for_topic_with_primary_key
belongs_to_counter_cache_before_destroy_for_topic_with_primary_key
Bạn sẽ có thể thực hiện theo một quá trình tương tự trong chương trình của bạn để xác định tên phương pháp bổ sung bởi ActiveRecord để bạn có thể loại bỏ chúng sau existing instructions for removing callbacks.
Lựa chọn của bạn từ các tùy chọn ở trên thực sự phụ thuộc vào cấu trúc chương trình của bạn và sự cân bằng mà bạn sẵn sàng cân nhắc để tăng hiệu quả tải dữ liệu. Đáng lưu ý là hai tùy chọn đầu tiên có thể làm cho mã của bạn ít có thể đọc được bằng cách sửa đổi hành vi của lớp từ bên ngoài (vá khỉ) và có thể làm cho hệ thống của bạn không ổn định bằng cách bỏ qua các quy tắc nghiệp vụ (cập nhật các cột bộ nhớ cache) về cập nhật dữ liệu. Vì những lý do này, tôi sẽ suy nghĩ về việc liệu bạn có thể tạo một lớp khác để tải dữ liệu của bạn một cách tối ưu hóa trong khi giảm thiểu tác động đến khả năng đọc hoặc tính nhất quán của dữ liệu.
Bạn đã giải quyết vấn đề này chưa? Cùng một vấn đề ... –