0

私は次のモデルを持っています:

    class Word{

          ...........
/**
 * @ManyToOne(targetEntity="Language", cascade={"persist"})
 * @JoinColumn(name="language_id", referencedColumnName="id")
 */

protected $language;

   ..........................    

}

     class Language{
/**
 * @Id
 * @Column(type="integer", nullable=false)
 * @GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @Column(type="string", unique=true, nullable=false)
 */
protected $language;

 ........
}

データベースには 3 つの異なる言語の 3 つのレコードがあります。言語はユニークです。

新しい単語を作成し、それを既存の言語の 1 つに関連付けることができません。つまり、Word の FK を言語の PK に設定する方法を知りたいです。また、モデル内の FK は int ID ではなくオブジェクト参照として存在するため、実装方法について混乱しています。Doctrine_Query::create()-> を使用しようとしましたが、それも失敗しました。

私はこれを試しました:

    $this->em = $this->doctrine->em;

    $w = $this->input->post('word');
    $d = $this->input->post('description');

    $desclan = $this->input->post('desclan'); //language is selected from a drop down 
                                              //list populated from the DB 
    $wordlan = $this->input->post('wordlan');

        $word = new Entity\Word;
        $description = new Entity\Description;
        $language = new Entity\Language;

        $language->setLanguage($wordlan);
        $language->setLanguageId($lanId); // assuming that $lanId is obtained from DB


        $word->setWord($w);
        $word->setLanguage($language);
        $description->setDescription($d);
        $word->setDescrp($description);

        $this->em->persist($word);
        $this->em->flush();

言語はドロップダウン リストで選択します。もちろん、このコードは、言語がデータベースに既に存在することを吐き出します。Doctrineコードを介して、言語のIDを取得し、データベースの「単語」テーブルにFK language_idとして配置するにはどうすればよいですか?

前もって感謝します!

4

2 に答える 2

0

さて、今日ようやく解決しました... 解決策はとてもシンプルで、完全に盲目でした。Doctrine の機能について、私は明らかに適切に考えていませんでした。

最初にこれを試しました:

    $this->em->getConnection()->executeQuery("Update word set language_id = ? where word = ?", array($this->langIds[$wordlan], $w));

既存の言語を単語に設定するためですが、ORM を使用する目的に反するため、適切な解決策ではありません。今日、電球が消えたばかりで、ドクトリンが取得したオブジェクトとDBの間の接続を維持しているため、私は理解しました。例えば:

    $word_check = $this->em->getRepository('Entity\Word')->findOneBy(array('word' => $w));

'where word = $w' という単語を返します。この単語を単純に変更して $em->flush(); を呼び出すと、違いがデータベースに保存されます。したがって、必要な言語オブジェクトを取得して新しい単語に追加し、$em->flush(); を呼び出すと、単純に考えました。言語の新しいオブジェクトを作成して単語に追加するのではなく、既存の言語と新しい単語の間の FK を介して DB に接続を作成する必要があります。この新しいオブジェクトは同じ ID と文字列の単語を持っていますが、それを新しいオブジェクトとして扱い、doctrine はそれを新しいエントリとして言語テーブルに保存しようとします。したがって、「一意の言語」の制約のために例外を吐き出します。設定しました。したがって、このコードは単純に機能します。

    $new_w = new Entity\Word;

            $new_w->setWord($w);

            $lang = $this->em->getRepository('Entity\Language')->findOneBy(array('language' => $selected_language));

            $new_w->setLanguage($lang);                                

            $this->em->flush();

したがって、これは単に既存の言語を新しく作成する単語に追加し、FK を正しく設定するだけです。この投稿で私が探していたものを理解するのが難しい場合は申し訳ありませんが、現在は解決されているため、誰かが役立つことを願っています.

于 2013-11-08T16:03:45.603 に答える
0

フォームで何を投稿しているのかを知ることは非常に重要です。

$desclan = $this->input->post('desclan'); //language is selected from a drop down 
                                              //list populated from the DB

ここで、言語はドロップダウン リストから選択され、DB から取り込まれるとおっしゃいましたが、フォームに何が投稿されているのかお尋ねします。ドロップダウン リストには、データベースに既に存在する言語の ID が表示される可能性があります。正しい言語を見つけるだけです。

$languageFind = $entityManager->find('Entity\Language', $lanId); // $lanId is posted via form

次に、単語に言語を追加します。

$word->setLanguage($languageFind);

PS: 「言語は既に存在します」というエラーは、次の理由によるものです。

$language->setLanguageId($lanId); // assuming that $lanId is obtained from DB

データベースに既に存在する $lanId を使用して、新しい Language クラス インスタンスの setLanguageId() を実行することはできません。

于 2013-11-07T13:24:07.077 に答える