samedi 26 décembre 2015

Not attaching id's in laravel 5.2, many to many relationship

Consider the following: Posts can have many tags, tags have many posts.

class Tags extends Model {
    protected $table        = 'tags';
    protected $fillable     = ['tag', 'blog_id'];

    public function blog() {
        return $this->belongsTo(BlogsEntity::class, 'blog_id');
    }

    public function post() {
        return $this->belongsToMany(PostsEntity::class);
    }
}

class Posts extends Model {
    protected $table        = 'posts';
    protected $fillable     = ['title', 'content', 'blog_id'];

    public function blog() {
        return $this->belongsTo(BlogsEntity::class, 'blog_id');
    }

    public function tags() {
        return $this->belongsToMany(TagsEntity::class);
    }

    public function categories() {
        return $this->belongsToMany(CategoriesEntity::class);
    }
}

Migrations

    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('blog_id');
        $table->string('title');
        $table->string('content');
        $table->timestamps();
    });

    Schema::create('tags', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('blog_id');
        $table->string('tag');
        $table->timestamps();
    });

    Schema::create('post_tag', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('post_id');
        $table->integer('tag_id');
        $table->timestamps();
    });

Now lets insert a post, an insert some tags:

    $post = PostsEntity::create([
        'title'     => $post->title(),
        'content'   => $post->content(),
        'blog_id'   => $blog->id()
    ]);

    if (!$post) {
        return false;
    }

    $post->tags()->attach($this->tagIds);
    $post->categories()->attach($this->categoryIds);

    return true;

$this->tagIds and $categoryIds are an array of integers relating to the tag and category's after being created, for example., this is how we create tags when a post is created:

protected function createTagsForPost(Tags $tags, Blog $blog) {
    if (!empty($tags->tags())) {
        foreach ($tags->tags() as $tag) {
            if (is_null(TagsEntity::where('tag', $tag)->first())) {
                $createdTag = TagsEntity::create([
                    'tag'     => $tag,
                    'blog_id' => $blog->id()
                ]);

                if (!$createdTag) {
                    return false;
                }

                array_push($this->tagIds, $createdTag->id);
            }
        }
    }
}

Super simple.

So now that we created a tag, lets look in our data base and see whats been created:

scotchbox=# select * from tags;
 id | blog_id |    tag     |     created_at      |     updated_at      
----+---------+------------+---------------------+---------------------
  6 |       1 | asdasdas   | 2015-12-26 20:25:24 | 2015-12-26 20:25:24

scotchbox=# select * from categories;
 id | blog_id | category |     created_at      |     updated_at      
----+---------+----------+---------------------+---------------------
  1 |       1 | 123123   | 2015-12-26 20:51:36 | 2015-12-26 20:51:36

scotchbox=# select * from posts;
 id | blog_id | title  | content |     created_at      |     updated_at      
----+---------+--------+---------+---------------------+---------------------
  3 |       1 | qweqwe | qweqwew | 2015-12-26 20:56:46 | 2015-12-26 20:56:46

scotchbox=# select * from post_tag;
 id | post_id | tag_id | created_at | updated_at 
----+---------+--------+------------+------------
(0 rows)

scotchbox=# select * from category_post;
 id | post_id | category_id | created_at | updated_at 
----+---------+-------------+------------+------------
(0 rows)

As we can clearly see no tag id was attached to a post, no category id was attached to a post. the question I have for you is: Why?.

If We look at the docs for many to many I think my models are set up correctly. If we read:

To define this relationship, three database tables are needed: users, roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.

Ok done. They are named properly and have appropriate fields ...

To define the inverse of a many-to-many relationship, you simply place another call to belongsToMany on your related model. To continue our user roles example, let's define the users method on the Role model:

Ok Done that ... Tags is set up properly.

So lets jump down to handling these types of relationships

To attach a role to a user by inserting a record in the intermediate table that joins the models, use the attach

Ok thats done, I pass in an array of id's

So .... why is this not attaching?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire