其分解到最低例如:上重用範圍如過濾器`includes`急切裝載
class User < ActiveRecord::Base
has_many :profiles
has_many :addresses, through: :profiles
end
class Profile < ActiveRecord::Base
belongs_to :user
has_many :addresses
end
class Address < ActiveRecord::Base
belongs_to :profile
def self.active_by_date
where(is_active: true).order('updated_at DESC')
end
end
class UsersController < ApplicationController
def index
@users = User.includes(profiles: :addresses)
end
end
假設在上述控制器動作,我想急於加載活性地址,按日期排序,爲每個用戶的配置文件。我可以這樣做:
class User < ActiveRecord::Base
has_many :profiles
has_many :addresses, through: :profiles
has_many :active_addresses_by_date, through: :profiles,
source: :addresses, class_name: Address,
conditions: ['address.is_active = ?', true],
order: 'address.updated_at DESC'
end
class UsersController < ApplicationController
def index
@users = User.includes(profiles: :active_addresses_by_date)
end
end
但因爲我不能重複上Address
的active_by_date
範圍,條件和訂單,現在在兩個地方存在。我想幹這個,所以和第一個版本一樣,只有在Address
模型中才有「按日期激活地址」的概念。理想情況下,在我看來,我可以打電話@users.each { |user| user.addresses.active_by_date }
而不發出任何疑問。這是可能的ActiveRecord下,如果是這樣,我會怎麼去呢?
幾天前我偶然發現了這個問題。我最終重寫了該協會的訪問者,但很想看看還有哪些其他解決方案。 – AlexBrand 2013-04-26 17:48:25
我不知道它甚至有可能重寫關聯方法,並且仍然具有「包含」功能,但我只是對它進行了測試,顯然是這樣。這是我的書中的一個改進,但它也增加了'用戶'模型中特定於「熱門加載」的「東西」的數量。像你一樣,我希望有更好的解決方案。 =) – Grantovich 2013-04-26 20:27:33