[英]Rails & Postgres: Join tables on an array
从概念上讲,我想做的是能够说:产品 a 有 5 种颜色可供选择,这将是一组颜色 ID。 这些颜色 ID 是链接到颜色表的键,颜色表包含颜色相关数据,例如十六进制表示、彩色图像等。 最后,我想将颜色表与产品表连接起来,以便提取与颜色相关的数据。
在我当前的设置中,我有两个表: products
和colors
。 在我的products
表中,我有一列 ( color_ids
),其中包含一个整数数组。 该数组保存colors
表中colors
的 ID。 为了在 Rails 中加入这两者,我在Product
类中创建了一个自定义 SQL 字符串,例如:
class Product < ApplicationRecord
has_many :colors
def self.custom_query
"SELECT * FROM products JOIN colors on colors.id = ANY(products.color_ids)
WHERE products.name = 'Some Product'"
end
end
我尝试使用关联( includes(:colors)
),但这似乎不起作用,因为主 ID 是一个 ID 数组。
有没有更优雅/ Rails 的方式来实现我想要做的事情?
使用简单的has_and_belongs_to_many关联。 不要将您的参考 ID 存储在数组中,仅仅因为 PostgreSQL 允许您这样做,这不是关系数据库中应该如何实现关系。
# new migration
create_table :colors_products do |t|
t.references :color, foreign_key: true
t.references :product, foreign_key: true
end
add_index :colors_products, [:color_id, :product_id], unique: true
class Product < ApplicationRecord
has_and_belongs_to_many :colors
end
class Color < ApplicationRecord
has_and_belongs_to_many :products
end
所有的 ActiveRecord 方法都将起作用。
为什么不应该与数组建立关系(除非您真的知道自己在做什么):
你可以简单地做
class Product < ApplicationRecord
def colors
Color.where(id: color_ids)
end
end
class Color < ApplicationRecord
def products
Product.where('? = Any (category_ids)', id)
end
end
您可以创建一个名为如下的视图:
CREATE VIEW product_colors(id, product_id, name, hex, image) AS
SELECT
p.id as product_id,
c.name,
c.hex,
c.image
FROM
(
SELECT
id,
unnest(color_ids) as color_id
FROM
products
) as p
INNER JOIN colors c
ON c.id = p.color_id;
然后添加模型ProductColor
与
def readonly?
true
end
您可以将此视图视为子模型。 Products.includes(:product_colors)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.