Rails中为关联关系应用作用域:查询可用产品及变体
获取可用产品及对应可用变体的实现方案
嘿,我来帮你搞定这个需求!你已经有了Product的可用筛选scope,接下来咱们把ProductVariant的逻辑补全,再结合关联查询就能拿到想要的数据啦。
第一步:补全ProductVariant的Scope
首先把你没写完的ProductVariant的scope补完整,和Product保持一致的筛选逻辑:
class ProductVariant < ApplicationRecord belongs_to :product scope :only_enabled, -> { where(status: :enabled) } scope :only_in_stock, -> { where('quantity > 0') } scope :only_available, -> { only_enabled.only_in_stock } end
第二步:实现关联查询的几种方式
方式一:直接查询可用产品,同时预加载并过滤可用变体
如果你想一次性拿到所有可用产品,并且每个产品只带它的可用变体,可以用includes结合条件,或者用eager_load(适合需要对变体加过滤条件的场景):
# 方法1:用includes + where过滤变体 available_products = Product.only_available.includes(:product_variants).where(product_variants: ProductVariant.only_available.where_values_hash) # 方法2:用eager_load(会生成左连接,更适合带过滤的预加载) available_products = Product.only_available.eager_load(:product_variants).merge(ProductVariant.only_available)
这样拿到的available_products里,每个产品的product_variants属性只会包含可用的变体。
方式二:在Product模型里定义专属关联
如果经常需要获取产品的可用变体,可以直接在Product模型里定义一个关联,这样用起来更方便:
class Product < ApplicationRecord has_many :product_variants has_many :available_product_variants, -> { only_available }, class_name: 'ProductVariant' # 你的原有scope scope :only_enabled, -> { where(status: :enabled) } scope :only_in_stock, -> { where('quantity > 0') } scope :only_available, -> { only_enabled.only_in_stock } end
之后查询的时候就可以直接预加载这个专属关联:
available_products = Product.only_available.includes(:available_product_variants)
这样每个产品的available_product_variants就是它的可用变体集合啦。
方式三:确保只返回有可用变体的产品(可选)
如果你还需要过滤掉没有任何可用变体的产品,可以在查询里加上joins来关联变体:
available_products_with_variants = Product.only_available.joins(:product_variants).merge(ProductVariant.only_available).distinct
这里的distinct是为了避免同一个产品因为多个变体而被重复返回。
内容的提问来源于stack exchange,提问作者justapilgrim
相关产品推荐
相关产品推荐

