簡體   English   中英

Rails 和 Postgres:在數組上連接表

[英]Rails & Postgres: Join tables on an array

從概念上講,我想做的是能夠說:產品 a 有 5 種顏色可供選擇,這將是一組顏色 ID。 這些顏色 ID 是鏈接到顏色表的鍵,顏色表包含顏色相關數據,例如十六進制表示、彩色圖像等。 最后,我想將顏色表與產品表連接起來,以便提取與顏色相關的數據。

在我當前的設置中,我有兩個表: productscolors 在我的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 方法都將起作用。

為什么不應該與數組建立關系(除非您真的知道自己在做什么):

  1. 您不能使用外鍵。 您將能夠在您的數組中擁有一個不再在數據庫中的 color_id。
  2. 如果您刪除一種顏色,您的數據庫將無法自動清除所有產品的 ID。
  3. ActiveRecord(和大多數 ORM)根本不起作用,您將需要大量的解決方法。

你可以簡單地做

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM