11

私は2つのモデルを持っていClientますSecurity. これらは、HATBTM 関係に関連付けられています。という結合テーブルを作成しましたclients_securities。したがって、aClientは多くの証券を持つことができ、a は多くの sSecurityに属することができます。Client

ここに画像の説明を入力

これが私の関係の定義です:

 //Client Model:
public $hasAndBelongsToMany = array(
    'Security' =>
        array(
            'className' => 'Security',
            'joinTable' => 'clients_securities',
            'foreignKey' => 'client_id',
            'associationForeignKey' => 'security_id',
            'unique' => true,
        )
);

 //Security Model:
public $hasAndBelongsToMany = array(
    'Client' =>
        array(
            'className' => 'Client',
            'joinTable' => 'clients_securities',
            'foreignKey' => 'security_id',
            'associationForeignKey' => 'client_id',
            'unique' => true,
        )
);

次に、クライアント コントローラーで編集アクションを作成し、次のようにしました。

public function edit($id = null) {
        if (!$id) {
            throw new NotFoundException(__('Invalid client'));
        }

        $client = $this->Client->findById($id);
        if (!$client) {
            throw new NotFoundException(__('Invalid client'));
        }

        if ($this->request->is('post') || $this->request->is('put')) {
            $this->Client->id = $id;
            if ($this->Client->saveAll($this->request->data)) {
                $this->Session->setFlash(__('Client has been updated.'));
                return $this->redirect(array('action' => 'edit', $id));
            }
            $this->Session->setFlash(__('Unable to update client.'));
        }

        if (!$this->request->data) {
            $this->request->data = $client;
            $this->set('securities', $this->Client->Security->find('list'));
        }
    }

編集ビューで、HtmlHelper を使用してフォームを作成し、クライアント テーブル フィールドを追加して、次のように複数選択を生成します。

echo $this->Form->create('Client'); //start the form for the client model
echo $this->Form->input('Security'); //generates a multi-select popuplated with securities

さらにClient、同じフォームの通常の直接フォーム入力もあります。例えば

echo $this->Form->input('name'); //Input for the client name
echo $this->Form->input('currency'); //Input for the client currency
...

これらすべての入力は、フォームがレンダリングされるときに生成され、正しい値が取り込まれますが、複数選択からの HABTM データではなく、直接のクライアント データのみが保存されます。

フォームを送信すると、clients_securitiesテーブルに結合 ID が入力されません。

正しく保存し、「編集」ビューをリロードするときに保存された証券を事前に選択するにはどうすればよいですか。


編集:物事を明確にするために、ここにのがpr()あり$this->request->dataます。(値 ("ALLCMCT LX Equity") はsecuritiesテーブルの正しい外部キーです):

Array
(
    [Client] => Array
        (
            [id] => 1212
            [name] => Example Client
            [currency] => GBP
            [partner] => 
            [risk_category_id] => 4
            [client_code_id] => 1
            [min_cash_balance] => 0
            [active] => 1
            [model] => 0
            [institutional] => 0
            [non_uk_situs] => 0
            [reporting_status] => 0 
        )

    [Security] => Array
        (
            [Security] => Array
                (
                    [0] => .1muslib3 index
                    [1] => .eurib3 index
                    [2] => .ukcpi2 index
                )

        )

)

基本的に、私のクライアント ID が 12345 だとすると、Cake は次のclients_securitiesようにテーブルに 2 つのレコードを挿入する必要があります。

id | client_id | security_id
----------------------------
1  | 12345     | ALLCMCT LX Equity
2  | 12345     | APMKNTD LX Equity

いくつかの結合レコードを に手動で追加するclients_securitiesと、クライアントを編集するときに、複数選択の証券が正しく事前選択されて表示され、結合テーブルからデータが読み取られていることが示されます。フォームを保存すると、実際には結合レコードが削除されますが、新しいレコードは保存されません。

追加メモ:私のセキュリティ ID は、何らかの影響がある場合はCHAR(36) として保存されます。これは自動インクリメント フィールドではなく、証券のティッカーが含まれており、それぞれが一意です。

4

6 に答える 6

5

問題は and の形式にありますsecurity_id: Security.idchar はサポートされていません。

このチケットを見つけました(ただし、ドキュメントには参照がありません)

idHABTM 関連付けで使用する数値を含む別の列を作成する必要があります

于 2013-09-27T06:29:45.277 に答える
1

フォーム入力を次のように変更します。

echo $this->Form->input('Security.Security');
于 2013-09-24T22:42:00.473 に答える
0

両方のモデルにデータを入力した後、メディエーター テーブルにデータを入力するための ID がないため、メディエーター テーブルにデータを入力していません。したがって、メディエーターテーブルにデータを入力するユーザー beforeSave および afterSave 関数。Client モデルに beforesave 関数を追加

public function beforeSave($options = array()) {
        parent::beforeSave($options = array());
            foreach (array_keys($this->hasAndBelongsToMany) as $model):
                if(isset($this->data[$this->alias][$model])):
                    $this->data[$model][$model] = $this->data[$this->alias][$model];
                    unset($this->data[$this->alias][$model]);
                endif;
            endforeach;
        return true;
    }

また、セキュリティ ユーザーの AfterSave 機能では、

public $securityIdArray = array();

public function afterSave($created) {
        if($created) {
            $this->securityIdArray[] = $this->getInsertID();
        }
        return true;
    }

最初にセキュリティを保存し、コントローラに $this->Model->save した後、$securityIdArray を使用してセキュリティの ID を取得します。

$this->Security->securityIdArray[] = $void['Security']['id'];

@Ariliaが言ったように、フォーラムの入力フィールドを変更します

echo $this->Form->input('Security.Security');

両方のモデルに別々のフォームを作成しないでください

于 2013-09-26T21:56:30.913 に答える
0
<?php 
Model::saveAssociated(array $data = null, array $options = array());

or

Model::saveAll(array $data = null, array $options = array());
?>

詳細については、http: //book.cakephp.org/2.0/en/models/ Saving-your-data.htmlをご覧ください。

于 2013-09-19T11:37:41.247 に答える
0

やってみます...

$this->Client->read(); を忘れていました。$this->Client->id = $id; の後 edit() 関数内 ($this->Client の内部は初期化されていないため、保存が完了した時点では client_id は存在しません)。呼び出し "findById" は配列のみを返しますが、データをオブジェクト $this->Client に読み込みません。

ちょうど良い経験に基づいた推測..

于 2013-09-25T19:12:02.223 に答える