2012-05-09 11 views
3

私のRails3アプリでは、私はActiveRecordPostgresqlを使用しています。ユーザーが動的モデル属性を作成できるようにしますか?

というモデルがあります。モデルには、価格、数量などの標準的な属性の小さなリストがあります。

ただし、顧客AはLotNumberを追加し、得意先BはOriginalLocationを追加することがあります。

どうすればいいですか?

私はPartsDetailモデルを作成して、タイプを持つことを許可しました。

class PartsDetail < ActiveRecord::Base 
    attr_accessible :type, :value, :part_id 
    belongs_to :parts 
end 

「タイプ」は「LotNumber」することができるように、など

しかし、私はそれが私の団体や照会にどのように動作するかはかなりよく分かりません。

アイデア?

ありがとうございました。あなたは、PostgreSQLを使用しているので

+1

SQLの場合:どちらか動的スキーム(新しい列)、列内の非正規化(例えば、 JSON)、または列内のスキーマ(たとえばEAV)を表すスキーマです。 –

+3

顧客をデータベース設計者として雇用するのは本当に危険なアプローチです。 –

+1

@Catcall必ずしも「データベース設計者」であるとは限りません(これは、この質問の内容よりもはるかに大きなコンテキストを意味します)。しかし、*ビジネス要件のために*追加の "カスタム"プロパティをエンティティに付加することはかなり共通しています*。 *これを(何らかの形で)許可することは、ビジネス特有のニーズに対してマイナスになることがあります。 (この場合、CustomerBにはOriginalLocationが必要です) –

答えて

3

は、データベースの列に任意のハッシュを格納するのにhstoreを使用することができます。

このモジュールは、単一のPostgreSQL値内のキー/値のペアのセットを格納するためのhstoreのデータ型を実装します。これは、まれに検査される多くの属性を持つ行や半構造化されたデータなど、さまざまなシナリオで役立ちます。キーと値は単なるテキスト文字列です。

のActiveRecordにhstoreサポートを追加するためにも宝石があります:

https://github.com/softa/activerecord-postgres-hstore

は次にあなたが言う、と呼ばれるhstore列、client_specificを作成して、のようなもので、その内部になります:

M.where("client_specific -> 'likes' = 'pancakes'") 
M.where("client_specific @> 'likes=>pancakes'") 

で、どのクライアントがパンケーキが好きであるかを確認しました。

顧客固有のフィールドのリストを顧客レコードのどこかに格納して、UIの側面を扱いやすくすることができますが、これはかなり簡単です。

+0

このアプローチはEAVソリューションより優れているのでしょうか、それとも同じものでしょうか?必要とされる動的属性は、「めったに検討されていない」ものよりもはるかに多いものです。彼らは彼らのモデルの鍵です。ありがとう – cbmeeks

+0

@cbmeeks:これはEAVと全く同じではありませんが、これは基本的にストリング間のハッシュを列タイプとして追加します。特別なテーブルや結合を必要とせず、さまざまな 'serialize'アプローチとは異なり、' hstore'カラムは他のものと同様に完全にインデックス可能です。 PostgreSQLには、特に 'hstore'用の関数と演算子のスイートがありますので、EAVを通して手作業で行うよりも簡単かもしれません。 –

+1

hstoreをレールに使用していくための上質なブログ記事:http://neilmiddleton.com/the-wonders-of-hstore/ – jacklin

1

ここで誰かがそれはあなたがhstoreのがよりシームレスにあなたのモデルで属性を使用することができます書いたことを要旨です:https://gist.github.com/2834785

初期化子でこれを追加(またはactive_record_extensionsと呼ばれる新しい初期化子を作成使用するには。RB)

require "hstore_accessor" 

は、その後、あなたのモデルでは、あなたが持つことができます:あなたがすることができます

Class User < ActiveRecord::Base 
    hstore_accessor :properties, :first_name, :last_name 
end 

:あなたはまだhstoreの列に属性を追加し、バイパス行うことができ

u = User.new 
u.first_name = 'frank' 

をhstore_attributes though:

関連する問題