在rails上使用ruby,我有一個Customer表,我希望能夠添加無限的屬性(鍵值對)。我不確定鍵/值對會是什麼,所以我不知道如何做到這一點。例如,一個客戶可能是:ActiveRecord模型的無限任意屬性(鍵/值對)
- 客戶1個屬性:
- 顏色: '黃'
- 品牌: '耐克'
- 銷售: '33'
- 客戶2性能:
- 顏色:'紅'
- phone_numb ER: '1111111111'
- 購買: '2'
基本上,客戶可以具有任何數量的鍵/值對的特性。
我該怎麼做?
在rails上使用ruby,我有一個Customer表,我希望能夠添加無限的屬性(鍵值對)。我不確定鍵/值對會是什麼,所以我不知道如何做到這一點。例如,一個客戶可能是:ActiveRecord模型的無限任意屬性(鍵/值對)
基本上,客戶可以具有任何數量的鍵/值對的特性。
我該怎麼做?
您應該可以使用serialize來實現此目的,並將屬性散列分配給您的屬性屬性,並以相同的方式檢索它們。
執行此操作的「傳統」方法是使用實體屬性值或EAV模式。顧名思義,您將創建一個包含三列的新表:一個用於「實體」,在本例中爲Customer,一個用於「屬性」名稱或鍵,另一個用於值。所以,你有一個像這樣的表:
customer_properties
+----+-------------+--------------+------------+
| id | customer_id | key | value |
+----+-------------+--------------+------------+
| 1 | 1 | color | yellow |
| 2 | 1 | brand | nike |
| 3 | 1 | sales | 33 |
| 4 | 2 | color | red |
| 5 | 2 | phone_number | 1111111111 |
| 6 | 2 | purchases | 2 |
+----+-------------+--------------+------------+
你肯定會想在key
和索引當然也許上value
(和customer_id
,但Rails會爲你做的,當你使用relation
或在您的遷移中使用belongs_to
)。
然後在您的機型:
# customer.rb
class Customer < ActiveRecord::Base
has_many :customer_properties
end
# customer_property.rb
class CustomerProperty < ActiveRecord::Base
belongs_to :customer
end
這使得使用這樣的:
customer = Customer.joins(:customer_properties)
.includes(:customer_properties)
.where(customer_properties: { key: "brand", value: "nike" })
.first
customer.customer_properties.each_with_object({}) do |prop, hsh|
hsh[prop.key] = prop.val
end
# => { "color" => "yellow",
# "brand" => "nike",
# "sales" => "33" }
customer.customer_properties.create(key: "email", value: "[email protected]")
# => #<CustomerProperty id: 7, customer_id: 1, key: "email", ...>
由於數據庫設計去,這是非常穩固的,但你可以看到它有一定的侷限性:在特定的,這很麻煩。此外,您僅限於一種值類型(常見的爲:string
/VARCHAR
)。如果你走這條路線,你可能想要在Customer上定義一些便利的方法來使訪問和更新屬性變得不那麼麻煩。我猜測有可能是專門用於使EAV模式與ActiveRecord一起工作的寶石,但我不知道它們是否在我頭頂,我希望你能原諒我不使用谷歌搜索,因爲我是移動設備。
布拉德·韋斯指出,如果你只需要存儲的任意屬性,而不是由他們查詢,serialize
是一個偉大的選擇,如果你使用PostgreSQL連查詢的問題是可以克服由於其巨大的hstore功能。
祝你好運!
正確的,你救了我的麻煩 - 說得好! –
哇,很好的回答(你也是,布拉德)。我使用序列化,但這也非常有趣。非常感謝 –
有誰知道在多個Rails模型中使用這種模式的任何標準Rails gems? –
您可能想要查看hydra_attribute gem,它是ActiveRecord模型的實體 - 屬性 - 值(EAV)模式的實現。
然而,這將使得通過這些屬性查詢(即使不是不可能)也很困難。 –
這取決於使用的數據庫。 Postgres很容易支持 - http://travisjeffery.com/b/2012/02/using-postgress-hstore-with-rails/ –
是的,如果你安裝了寶石。 –