[英]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.