与 Rails 的深度模型关联



假设我有一个CPA跟踪系统。

我会有以下模型:一个报价,它有一些着陆,每个着陆都有多个链接,每个链接都有一堆访问。

所以,我想要的是 DRY 代码,因此访问表中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 .但是,如果我需要一个优惠相关的不同访问怎么办?

问题是我无法使用活动记录 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)

最新更新