Adding Data to multiple tables with a single form Laravel

17,089

Solution 1

Based on the comments and discussion you have a couple of issues. The original MassAssignmentException was due to the fact that you have a custom base model in which you define a single $fillable property for all the models. But you still referenced the default Eloquent model when extending your Tag model.

Then the next issue would be attaching the tags to the post. You're passing a space delimited tag value and you're planning to separate them when accessing. That's not how tags work when you use many-to-many relationship. You need to split the tags up before storing them and attach each one to the post.

public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required|max:48',
        'body' => 'required',
        'image' => 'required',
        'tags' => 'required|max:200'
    ]);

    $destination = 'uploads';
    $image = $request->file('image');
    $filename = $image->getClientOriginalName();
    $image->move($destination, $filename);
    $location = $destination . '/' . $filename;

    $post = Post::create([
        'title' => request('title'),
        'body' => request('body'),
        'user_id' => auth()->id(),
        'image' => $location
    ]);

    $tags = explode(' ', request('tags'));

    $tagInstances = [];

    foreach($tags as $tag) {
        $tagInstances[] = new Tag(['name' => $tag]);
    }

    $post->tags()->saveMany($tagInstances);

    return redirect('/blog');
}

Solution 2

I solve this exception and this exception throws when you have not define $table and $fillable in your each model separately.

protected $table = 'table_name';

protected $fillable = [fields which you define in your table];

visit https://laravel.com/docs/5.0/eloquent#mass-assignment then you can get clear understanding about this

Share:
17,089
Leo
Author by

Leo

Updated on June 29, 2022

Comments

  • Leo
    Leo almost 2 years

    I am trying to insert a blog post on db, I do have two tables posts and tags tables. When I insert the create the post I want to be able to insert the data from the form in those two different tables.

    create.blade.php;

    <div class="account_grid">
    
    <div class="col-md-6 login-right wow fadeInRight col-md-offset-3" data-wow-delay="0.4s">
        <h3>CREATE A BLOG POST</h3>
        <p>Please fill out the required fields *</p>
        <form method="post" action="/posts"  enctype="multipart/form-data">
             {{csrf_field()}}
            <div>
                <span>Title:<label>*</label></span>
                <input type="text" id="title" name="title"  > 
            </div>
            <div>
                <span>Body<label>*</label></span>
                <textarea id="body" name="body" rows="14"  ></textarea>
            </div>
            <div>
                <span>Tags:<label>*</label></span>
                <input type="text" id="tags" name="tags">
            </div>
            <div>
                <span>Image<label>*</label></span>
                <input type="file" name="image" id="image"  >
            </div>
            <input type="submit" value="Publish">
    
        </form>
    
    @include('layouts.errors')
    </div>  
    <div class="clearfix"> </div>
    </div>
    

    On my route file I have the path that leads to PostsController.php which has a store method like below:

    PostsController.php

        public function store(Request $request){
    
            $this->validate($request, [
    
                'title' =>'required|max:48',
                'body'=>'required',
                'image'=>'required',
                'tags' =>'required|max:200'
            ]);
    
            $post = new Post;
    
            $destination ='uploads';
            $image = $request->file('image');
            $filename = $image->getClientOriginalName();
            $image->move($destination, $filename);
            $location=$destination.'/'.$filename;
            $tags = request('tags');
    
    
               Post::create([
                'title'=>request('title'),
                'body' =>request('body'),
                'user_id'=>auth()->id(),
                'image' =>$destination.'/'.$filename
    
            ]);
    
            $tag = new Tag;
    
            Tag::create([
    
                'name' => $tags
            ]);
    
            return redirect('/blog');
        }
    }
    

    The thing is that when I call the method I want the form data to be saved on two different tables, I have tried like below but I am getting ERROR:

    MassAssignmentException in Model.php line 232: name

    I did research the issue but no luck; and yes I do have the 'name' listed in the protected $fillable array. Any suggestion on how to store data in two different tables or what type of relationship should i use.

    On post.php model i do have a relationship specified. Tags belongsToMany as well as on my tag.php model Post belongsToMany

    p.s New to Laravel.

    tag.php model:

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Tag extends Model
    {
        //
    
            public function posts(){
    
            return $this->belongsToMany(Post::class);
        }
    
        public function getRouteKeyName(){
    
            return 'name';
    
        }
    }
    

    Post.php model:

    <?php
    
    namespace App;
    use Carbon\Carbon;
    class Post extends Model
    {
    
        public function comments(){
    
            return $this->hasMany(Comment::class);
        }
    
        public function addComment($body, $name, $email, $user_id){
    
            $this->comments()->create(compact('body','name','email', 'user_id'));
        }
    
        public function user(){ // $comment->user->name
    
            return $this->belongsTo(User::class);
        }
    
        public function scopeFilter($query, $filters){
    
            if($month =$filters['month']){
    //            
                $query->whereMonth('created_at', Carbon::parse($month)->month);
            }
    
            if($year = $filters['year']){
    
                $query->whereYear('created_at',$year );
            }
        }
    
        public static function archives(){
            return static:: selectRaw('year(created_at)year, monthname(created_at)month, count(*) published')
           ->groupBy('year','month')
           ->orderByRaw('min(created_at) desc')
           ->get()
           ->toArray();
        }
    
        public function tags(){
    
            return $this->belongsToMany(Tag::class);
        }
    
    
    
    }