0

Ruby on Rails v3.2.2を使用していますが、クラス/インスタンス属性を「保護」して、データベーステーブルの列の値を一方向にしか更新できないようにします。つまり、たとえば、2つのデータベーステーブルがあるとします。

table1
- full_name_column

table2
- name_column
- surname_column

関連するクラス/モデルに記載されているコールバックを使用してが更新されるtable1ように管理し、そのコールバックを介してのみ値を更新できるようにしたいと思います。full_name_columntable2full_name_column

言い換えれば、が常にあることを確認する必要がありますtable2.full_name_column

"#{table1.name_column} #{table1.surname_column}"

そしてそれは別の値になることはできません。したがって、たとえば、を「直接」更新しようとするとtable1.full_name_column、エラーのようなものが発生するはずです。もちろん、その値は読み取り可能でなければなりません。

出来ますか?この状況に対処するためにあなたは何をアドバイスしますか?


このアプローチの理由...

「profile」/「person」オブジェクトに関連する他の値が含まれているtable1列でデータベース検索を実行することを計画しているため、このアプローチを使用したいと思います。table1それらの検索をtable2soに転送して、"#{table1.name_column} #{table1.surname_column}"文字列を検索します。

したがって、簡単な方法は上記で説明したようにデータを非正規化することだと思いますが、そのデータを処理するための「珍しい」方法を実装する必要があります。

ところで:答えは、関連するプロセスを「解決」すること、または検索機能をより良い方法で処理するためのより良いアプローチを見つけることを意図する必要があります。

4

2 に答える 2

2

データベースレベルでデータを維持するための2つのアプローチがあります...

ビューとマテリアライズドテーブル。

可能であれば、table1はVIEWまたはたとえばMATERIALIZED QUERY TABLE(MQT)にすることができます。使用するRDMSによっては、用語が多少異なる場合があります。OracleにはMATERIALIZED VIEWがありますが、DB2にはMATERIALIZEDQUERYTABLEがあります。

VIEWは、物理的に別のテーブルにあるデータへのアクセスです。一方、MATERIALIZED VIEW / QUERY TABLEはデータの物理コピーであるため、たとえば、リアルタイムでソースデータと同期していません。

ともかく。これらのアプローチは、table2が所有しているが、table1がアクセスできるデータへの読み取り専用アクセスを提供します。

非常に単純なビューの例:

CREATE VIEW table1 AS 
   SELECT surname||', '||name AS full_name
     FROM table2;

トリガー

他の場所からは利用できないデータをtable1に実際に入れたい場合があるため、ビューが便利でない場合があります。このような場合、データベーストリガーの使用を検討できます。つまり、table2が更新されると、同じデータベーストランザクション内でtable1も更新されるトリガーを作成します。

トリガーを使用すると、table1も更新するためにクライアントに特権を付与する必要があるという問題が発生する可能性があります。一部のRDMSは、トリガーのアクセス制御を調整するいくつかの方法を提供する場合があります。つまり、TRIGGERによって実行される操作は、TRIGGERを開始する操作とは異なる特権で実行されます。

この場合、TRIGGERは次のようになります。

   CREATE TRIGGER UPDATE_NAME
     AFTER UPDATE OF NAME, SURNAME ON TABLE2
     REFERENCING NEW AS NEWNAME
     FOR EACH ROW
     BEGIN ATOMIC
       UPDATE TABLE1 SET FULL_NAME = NEWNAME.SURNAME||', '||NEWNAME.NAME
        WHERE SOME_KEY = NEWNAME.SOME_KEY
     END;
于 2012-04-27T15:53:09.153 に答える
1

table2からtable1にデータを複製することにより、データはすでに非正規化されています。他の非正規化と同様に、同期の維持については訓練を受ける必要があります。これは、想定外のものを更新しないことを意味します。

偶発的な割り当てを防ぐために壁を張ることはできますがattr_accessible、Rubyの動作方法は、値が変更されないことを保証する方法がないことを意味します。誰かが十分に決心していれば、彼らは道を見つけるでしょう。これが規律の出番です。

最善のアプローチは、列を直接変更してはならないことを文書化し、で一括割り当てをブロックしattr_accessible、そのままにしておくことです。私の知る限り、書き込み保護された属性の概念は実際にはありません。

于 2012-04-27T15:15:14.337 に答える