将 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
您好,我正在尝试将此 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