Có thể ủy quyền một phương thức cho một hiệp hội has_many
trong đường ray, VÀ vẫn lưu dữ liệu đã tải trước vào liên kết đó, tất cả trong khi tuân theo luật của demeter? Hiện tại có vẻ như với tôi rằng bạn buộc phải chọn cái này hay cái kia. Tức là: giữ dữ liệu được tải sẵn của bạn bằng cách KHÔNG ủy quyền hoặc mất dữ liệu được tải trước của bạn và ủy quyền.Phương thức ủy nhiệm cho liên kết has_many bỏ qua việc nạp trước
Ví dụ: Tôi có hai mô hình sau:
class User < ApplicationRecord
has_many :blogs
delegate :all_have_title?, to: :blogs, prefix: false, allow_nil: false
def all_blogs_have_title?
blogs.all? {|blog| blog.title.present?}
end
end
class Blog < ApplicationRecord
belongs_to :user
def self.all_have_title?
all.all? {|blog| blog.title.present?}
end
end
Chú ý: đó User#all_blogs_have_title?
làm điều chính xác giống như các phương pháp phân cấp all_have_title?
.
Sau đây, như tôi đã hiểu, vi phạm pháp luật về demeter. Tuy nhiên: nó duy trì dữ liệu được tải trước của bạn:
user = User.includes(:blogs).first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Blog Load (0.1ms) SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" = 1
=> #<User id: 1, name: "all yes", created_at: "2017-12-05 20:28:00", updated_at: "2017-12-05 20:28:00">
user.all_blogs_have_title?
=> true
Lưu ý: khi tôi gọi user.all_blogs_have_title?
nó KHÔNG làm một truy vấn bổ sung. Tuy nhiên, lưu ý rằng phương thức all_blogs_have_title?
hỏi về các thuộc tính Blog
, vi phạm pháp luật về demeter.
cách khác mà áp dụng pháp luật của Demeter nhưng bạn bị mất dữ liệu tải trước:
user = User.includes(:blogs).first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Blog Load (0.1ms) SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" = 1
=> #<User id: 1, name: "all yes", created_at: "2017-12-05 20:28:00", updated_at: "2017-12-05 20:28:00">
user.all_have_title?
Blog Load (0.2ms) SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" = ? [["user_id", 1]]
=> true
Hy vọng rằng các nhược điểm của cả hai hiện thực là rõ ràng. Lý tưởng nhất: Tôi muốn làm điều đó theo cách thứ hai với việc thực hiện ủy nhiệm, nhưng để duy trì dữ liệu được tải sẵn đó. Điều này có thể không?