2

大量のデータを含む「AddOns」のモデルがあります。また、SO のように通常の方法で機能するタグもあり、コンマ区切りのリストから最大 5 つのタグを使用できます。

私が作成しようとしている動作は次のとおりです。

  • ユーザーがアドオンを作成
  • アドオンが作成されました
  • システムはタグを配列に分割し、それらをループします
  • システムがタグを検索し、存在する場合はその ID を使用します
  • タグが存在しない場合は、タグを作成してその ID を使用します
  • タグとアドオンの間にリンクを作成する

手動クエリを使用してこれを非常に簡単に行うことができますが、それが最善の方法であるか、どのようにアプローチすべきかはわかりません。これが私のコードです:

if ($this->request->is('post')) {
$this->AddOn->create();
$this->AddOn->set('user_id', $this->Auth->user('id'));
if ($this->AddOn->save($this->request->data)) {

    // Get the ID of the addon
    $addon_id = $this->AddOn->getInsertID();
    $tagsarr = explode(',', $this->request->data['Tag']['Tag']);
    foreach($tagsarr as $tag){
        $tagdb = $this->Tags->findByTagName(trim($tag));
        if(!empty($tagdb)){
            // HELP! We have a tag, but how do we add the link?
        } else {
            // Add the tag, but then how do we link it?
        }
        unset($tagdb);
    }

    $this->Session->setFlash(
        __('The %s has been saved', __('add on'))           
    );
    $this->redirect(array('action' => 'index'));
} else {
    $this->Session->setFlash(
        __('The %s could not be saved. Please, try again.', __('add on')),
    );
}
}

編集:私が達成しようとしていることのいくつかの疑似コードを以下に追加しました。

$AddOn->create();
$AddOn->save(); // Create AddOn
$AddOnID = $AddOn->insertId(); // Newly inserted AddOn's ID

$tagsArr = explode(',', $post->tags); // Make an array of tags [this,is,a,tag,list]
foreach($tagsArr as $tag){ // Loop through them
  $tagFromDb = $Tags->findTagByName($tag); // Try and find the tag from the tags table
  if(!$tagFromDb){ // Have we found it? No
    $tagId = $Tags->newTag($tag); // Add it and reference
  } else { // Have we found it? Yes
    $tagId = $tagFromDb->id; // Reference it
  }
  $AddOnTagsLink->addAddOnTagsLink($AddOnID, $tagId); // Add the link
}
4

1 に答える 1

1

これを実装するためのロジックは、コントローラーではなくモデルにある必要があります。before save コールバックを使用すると、「tags」フィールドをフォームに追加して通常どおり保存できます。

public function beforeSave($options = array()) {
    if (isset($this->data['AddOn']['tags'])) {
        $this->data['Tag'] = array();
        $submitted = array_map('trim', explode(',', $this->data['AddOn']['tags']));
        $existing = $this->Tag->find('list', array(
            'fields' => array('id', 'name'),
            'conditions' => array('name' => $submitted),
            'recursive' => -1
        ));
        foreach ($submitted as $tag) {
            if(!empty($tag)) {
                $id = array_search($tag, $existing);
                if (!$id) {
                    $this->Tag->save(array('name' => $tag));
                    $id = $this->Tag->id;
                }
                $this->data['Tag'][] = array('tag_id' => $id);
            }
        }
    }
    return true;
}

そのコードは、新しいタグsaveAllごとに 1 つではなく、クエリの数を 3 つ (既存の取得、欠落の作成、保存) に制限する 1 つのクエリ ( を使用) ですべての新しいタグを保存することで改善できますが、処理には追加の作業が必要です。返された ID。ユーザーが新しいタグを頻繁に作成する場合は、それを行う必要があります。

于 2013-05-13T23:56:30.147 に答える