将 Complex SQL 转换为 Activerecord

Convert Complex SQL to Activerecord

您好,我正在尝试将此 SQL 语句转换为我可以在我的 rails 项目

的控制器中使用的内容
    SELECT  "products".name, properties.display_name,variant_properties.description, variants.price FROM "products"
      INNER JOIN "product_properties" ON "product_properties"."product_id" = "products"."id"
      INNER JOIN  variant_properties on product_properties.property_id = variant_properties.property_id
      INNER JOIN "properties" ON "properties"."id" = "product_properties"."property_id" AND properties.id = variant_properties.property_id
      INNER JOIN  variants on variants.product_id = products.id AND variants.id = variant_properties.variant_id
    GROUP BY products.name, variant_properties.description,  properties.display_name, variants.price
    ORDER BY 1,2,4,3

最简单的方法是使用接受原始数据的活动记录连接方法作弊 SQL:

products = Product.select("products.name, properties.display_name, variant_properties.description, variants.price")
  .joins("INNER JOIN product_properties ON product_properties.product_id = products.id")
  .joins("INNER JOIN variant_properties on product_properties.property_id = variant_properties.property_id")
  .joins("INNER JOIN properties ON properties.id = product_properties.property_id AND properties.id = variant_properties.property_id")
  .joins("INNER JOIN variants on variants.product_id = products.id AND variants.id = variant_properties.variant_id")
  .group("products.name, variant_properties.description,  properties.display_name, variants.price")
  .order("products.name, properties.display_name, variants.price, variant_properties.description")

在您的模型中使用适当的关联,您可以将其简化为:

products = Product.select("products.name, properties.display_name, variant_properties.description, variants.price")
  .joins(:product_properties)
  .joins(:variant_properties)
  .joins(:properties)
  .joins(:variants)
  .group("products.name, variant_properties.description,  properties.display_name, variants.price")
  .order("products.name, properties.display_name, variants.price, variant_properties.description")

假设您有模型:

class Product
   has_many :product_properties
   has_many :variants
   has_many :properties, through: :product_properties

   LIST = 'products.name, variant_properties.description, properties.display_name, variants.price'

   scope :spec, -> {
      joins(:product_properties, :properties, :variants).
      merge(Property.strikt).
      merge(Variant.strikt).
      select(LIST).
      group(LIST).
      order('1,2,3,4')
   }
end 

class ProductProperty
   belongs_to :product
   belongs_to :property  
end

class VariantProperty
   belongs_to :variant
   belongs_to :property

   has_many :product_properties, foreign_key: :property_id, primary_key: :property_id
end

class Property
   has_many :variant_properties
   has_many :product_properties

   scope :strikt, -> { joins(:variant_properties).joins(:product_properties) }
end

class Variant
   belongs_to :product
   has_many :variant_properties

   scope :strikt, -> { joins(:product).joins(:variant_properties) }
end

所以你的 SQL 你应该从:

Product.spec.to_sql