Insert data to a pivot table in laravel

◇◆丶佛笑我妖孽 提交于 2020-11-26 08:10:47

问题


I have 3 tables: posts, tags, post_tag.

Each Post has many tags so I use hasMany method for them. But when I choose for example 3 tags in my dropdown list, I can't add them to post_tag and as the result I can't select and show each post's tags.

My Post model:

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

My Tag model:

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

}

And my 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();

I expect to save this post_id save to post_tag table with its tag ids, but it doesn't work. Thanks for your time.


回答1:


You have a basic idea right, but there are a few issues with your code. Some are stopping it from working and some are just conventional issues.

First off, this is a belongsTomany relationship (you have a pivot table) so you must define both sides of the relationship as belongsToMany (even if hasMany is the way you think about one or both of the side of it). This is because Laravel expects a certain database structure with the two different relationship types.

Another issue (that you found yourself) is that you are adding the tags to the relation (via ->tag()->sync() before you've actually saved the post. You must first save the post (so that laravel knows what ID to add to the pivot table for post_id) and then add the relations. If you are worried about the tags part failing and then having an inconsistent database you should use transactions.

Finally, the 'convention' errors you have is that a belongs-to-many relationship, by definition, involves collections of results. As such, tag and post shoudl be tags and posts respectively.

So here's my rewritten version of your code:

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');
        }
    }
}

Now a lot of that controller code centres around the transaction stuff - if you don't care too much about that then you're all good to remove it. Also there are several ways to do that transaction stuff - I've gone with one that's not ideal but gets the point across in a minimal amount of code.




回答2:


To insert you data into pivot table name diplome_user, just follow my example: my pivot table looking like:

//this is Diplome Model

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

now inside you my DiplomeController, I'm able to make this query:

$user = Auth::user(); 

because I need a user, I just take the connected one, after it, I create one instance of Diplome like:

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

now the most important step is:

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

Here is the result:




回答3:


The sync() method wants an array. It should work if you just put the tag id within one, like so:

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


来源:https://stackoverflow.com/questions/24547376/insert-data-to-a-pivot-table-in-laravel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!