web-dev-qa-db-ja.com

laravel)のピボットテーブルにデータを挿入します

poststagspost_tagの3つのテーブルがあります。

Postには多くのタグがあるので、それらにはhasManyメソッドを使用します。しかし、ドロップダウンリストでたとえば3つのタグを選択すると、それらをpost_tagに追加できず、その結果、各投稿のタグを選択して表示することができません。

私のPostモデル:

 class Post extends Eloquent{
 public function tag()
         {
           return  $this->hasMany('Tag');
         }
    }

私のTagモデル:

class Tag extends Eloquent{
 public function post()
         {
           return  $this->belongsToMany('Post');
         }

}

そして私のpostController

class postController extends BaseController{

public function addPost(){

    $post=new Post;

    $post_title=Input::get('post_title');
    $post_content=Input::get('post_content');
    $tag_id=Input::get('tag');

    $post->tag()->sync($tag_id);
    $post->save();

このpost_idをタグIDとともにpost_tagテーブルに保存する予定ですが、機能しません。御時間ありがとうございます。

10
saha

基本的な考え方は正しいですが、コードにはいくつかの問題があります。動作を停止しているものもあれば、従来の問題であるものもあります。

まず、これはbelongsTomany関係(ピボットテーブルがあります)であるため、関係の両側をbelongsToManyとして定義する必要があります(hasManyがあなたの考え方であっても)その側面の約片方または両方)。これは、Laravelは、2つの異なる関係タイプを持つ特定のデータベース構造を想定しているためです。

もう1つの問題(自分で見つけた)は、実際に投稿を保存する前に(->tag()->sync()を介して)リレーションにタグを追加していることです。最初に投稿を保存する必要があります(laravelは、post_id)のピボットテーブルに追加するIDを認識してから、リレーションを追加します。タグ部分が失敗し、データベースに一貫性がないことが心配な場合は、トランザクションを使用する必要があります。

最後に、あなたが持っている「従来の」エラーは、定義上、多くに属する関係には結果の収集が含まれるということです。そのため、tagpostはそれぞれtagspostsになります。

だからここにあなたのコードの私の書き直したバージョンがあります:

class Post extends Eloquent
{
    public function tags()
    {
        return $this->belongsToMany('Tag');
    }
}

class Tag extends Eloquent
{
    public function posts()
    {
        return $this->belongsToMany('Post');
    }
}

class PostController extends BaseController
{
    public function addPost()
    {
        // assume it won't work
        $success = false;

        DB::beginTransaction();

        try {
            $post = new Post;

            // maybe some validation here...

            $post->title = Input::get('post_title');
            $post->content = Input::get('post_content');

            if ($post->save()) {
                $tag_ids = Input::get('tags');
                $post->tags()->sync($tag_ids);
                $success = true;
            }
        } catch (\Exception $e) {
            // maybe log this exception, but basically it's just here so we can rollback if we get a surprise
        }

        if ($success) {
            DB::commit();
            return Redirect::back()->withSuccessMessage('Post saved');
        } else {
            DB::rollback();
            return Redirect::back()->withErrorMessage('Something went wrong');
        }
    }
}

現在、そのコントローラーコードの多くはトランザクション関連のものを中心にしています。それについてあまり気にしないのであれば、それを削除しても問題ありません。また、そのトランザクションを実行する方法はいくつかあります。理想的ではないものの、最小限のコードで要点を理解できる方法を採用しました。

8
alexrussell

ピボットテーブル名diplome_userにデータを挿入するには、次の例に従ってください。ピボットテーブルは次のようになります。

enter image description here

//this is Diplome Model

    class Diplome extends Model
    {
    public function users()
        {
            return $this->belongsToMany('App\User','diplome_user')->withPivot('etablissement', 'annee', 'mention');;
        }
    }

これで、DiplomeControllerの内部で、次のクエリを実行できます。

$user = Auth::user(); 

ユーザーが必要なため、接続されたユーザーを取得し、その後、次のようなDiplomeのインスタンスを1つ作成します。

$diplome = new Diplome();
$diplome->libelle = "the name";
$diplome->decription= "description of the ...";
$diplome->save();

今最も重要なステップは次のとおりです。

   $diplome->users()->attach($user, ['etablissement'=> 'bib',
                                            'annee'=>'2015',
                                            'mention'=>'AB',
                                            ]);

結果は次のとおりです。

enter image description here

7
Boston Kenne

sync()メソッドは配列を必要としています。次のように、タグIDを1つに入れるだけで機能するはずです。

$post->tag()->sync([$tag_id]);
4
Joel Hinz