[英]Deep model associations with Rails
假設我有一個CPA跟蹤系統。
我將使用以下模型:一個要約,它具有一些着陸點,每個着陸點都有多個鏈接,每個鏈接都有一堆訪問。
因此,我想要的是DRY代碼,因此visits表中的offer_id
列是不可接受的。 解決方法是這樣的委托方法:
class Offer < ActiveRecord::Base
has_many :landings
has_many :links, through: :landings
has_many :visits, through: :landings
end
class Landing < ActiveRecord::Base
belongs_to :offer
has_many :links
has_many :visits, through: :links
end
class Link < ActiveRecord::Base
belongs_to :landing
has_many :visits
delegate :offer, to: :landing
end
class Visit < ActiveRecord::Base
belongs_to :link
delegate :landing, to: :link
delegate :offer, to: :link
end
只需一次訪問即可很好地工作,例如visit.offer.id
。 但是,如果我需要與一個報價相關的不同訪問次數怎么辦?
問題是我無法使用ActiveRecord API構建有效的查詢。 它可能看起來像Visits.where(offer: Offer.first)
,但這種方式行不通,說ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: visits.offer: SELECT "visits".* FROM "visits" WHERE "visits"."offer" = 1
,這是可以預測的。
問題:如何組織代碼以使Visits.where(offer: Offer.first)
類的語句有效地工作,而又不重復訪問表中的offer_id
列?
您的代碼組織得很好,我認為不需要重構。 您可以通過在Visit
定義如下范圍來實現:
class Visit < ActiveRecord::Base
scope :from_offer, -> (offer) {
joins(link: :landing).where(ladings: {offer_id: offer.id})
}
scope :from_landing, -> (landing) {
joins(:link).where(links: {landing_id: landing.id})
}
end
因此查詢將是:
Visit.from_offer(Offer.first)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.