Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Hiiro's avatar
Level 2

[Solved] laravel 8 storing to database not work

first, i'm new to laravel, i just following tutorials from youtube

i have problem that store function does not work, this is forum website application using laravel 8. When user want to add a discussion : create discussion and when they finish input the data, nothing happenned , and nothing added on database basically, my code look like:

First the on the TopicController :

public function store(CreateTopicRequest $request)
    {
        $topic = new Topic;
        $topic = auth()->user()->$topic->create([
            'genre' => $request->genre,
            'title' => $request->title,
            'slug' => Str::slug($request->title),
            'description' => $request->description
        ]);

        session()->flash('success', 'Discussion posted!');

        return redirect()->route('topic.index');
    }

for topic model :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;


class Topic extends Model
{
    use HasFactory;

    protected $table = 'topics';
    protected $primaryKey = 'topicID';
    protected $fillable = ['genre', 'title', 'description', 'created_at', 'updated_at'];

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function getRouteKeyName()
    {
        return 'slug';
    }
}

for user model :

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\Relations\HasMany;
use app\Models\Topic;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     *
     */
    protected $table = 'users';
    protected $primaryKey = 'id';
    protected $fillable = [

        'nama',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function topics()
    {
        return $this->hasManyThrough(Topic::class, User::class);
    }

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }

    public function replies(): HasMany
    {
        return $this->hasMany(Reply::class);
    }
}
0 likes
34 replies
sr57's avatar

Any error ?

Did you put some dump / dd to see your code in action?

1 like
sr57's avatar

At the beginning of your store function.

How do you call it?

Just before the call in web.php

migsAV's avatar

Show us the form in your view file that is being used for the store method

Hiiro's avatar
Level 2

@migsAV

you mean this?

@extends('layout/main')


@section('title','Forum - Home')


@section('container')

<div class="container">
    <br>

    <div class="row justify-content-center">
        <main class="container py-4">
            <div class="row">
                <div class="col-md-4">
                    <br>
                    @auth
                    <a href="{{route('topic.create')}}" style="width: 100%; color: #fff" class="btn btn-info my-2">
                        Add Discussion
                    </a>
                    @else
                    <a href="{{route('login')}}" style="width: 100%; color: #fff" class="btn btn-info my-2">
                        Sign in to Add Discussion
                    </a>
                    @endauth
                    <div class="card">
                        <div class="card-header">
                            Genre
                        </div>
                        <div class="card-body">
                            <ul class="list-group">

                                @foreach($genres as $genre)
                                <li class="list-group-item">
                                    {{$genre->nama}}
                                </li>
                                @endforeach
                            </ul>
                        </div>
                    </div>
                </div>
                <div class="col-md-8">
                    @foreach($topics as $topic)
                    <div class="card">

                        @include('partials.topic-header')

                        <div class="card-body">
                            <div class="text-center">
                                {{$topic->title}}
                            </div>
                            <br><br>

                            <font size="2">
                                Created at : {{$topic->created_at}}<br>
                            </font>
                            <font size="2">
                                Updated at : {{$topic->updated_at}}
                            </font>
                            <br>
                            <div>
                                <a href="{{route('topic.show', $topic->slug)}}" class="btn btn-success btn-sm">View</a>
                            </div>
                        </div>
                    </div>
                    &nbsp;
                    @endforeach

                </div>
            </div>
    </div>



    @endsection
migsAV's avatar

@Hiiro no...it should have your form

<form action="{{ route('name_of_route') }}" method="POST">
## all the inputs
</form>
Hiiro's avatar
Level 2

@migsAV ohhh, i'm sorry

this one

@extends('layout/main')


@section('title','Forum - Create Discussions')




@section('container')
<div class="container">
    <br>
    <div class="row justify-content-center">
        <div class="col-md-15">

            <div class="card">
                <div class="card-header">{{ __('Add Discussions ') }}</div>

                <div class="card-body">
                    <form action="{{route('topic.store')}}" method="POST">
                        @csrf
                        <div class=form-group>
                            <label for="genre">Genre</label>
                            <br>
                            <select name="genre" id="genre" class="form-control">
                                @foreach($genres as $genre)
                                <option value="{{$genre->id}}">{{$genre->nama}}</option>
                                @endforeach
                            </select>
                        </div>
                        <br>
                        <div class="form-group">
                            <label for="floatingInput">Judul</label>
                            <br>
                            <input type="text" id="title" name="title" class="form-control" placeholder="Judul" required="required">
                        </div>
                        <br>
                        <div class="form-group">
                            <label for="description">Description</label>
                            <br>
                            <input id="description" type="hidden" name="description">
                            <trix-editor input="description"></trix-editor>
                        </div>

                        <br>
                        <button type="submit" class="btn btn-success">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    @endsection

    @section('css')
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/trix/1.3.1/trix.css">
    @endsection

    @section ('js')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/trix/1.3.1/trix.js">

    </script>
    @endsection
migsAV's avatar

Check that you have the authorize method to true in your CreateTopicRequest

public function authorize()
    {
        return true;
    }
Hiiro's avatar
Level 2

@migsAV here

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateTopicRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'genre' => 'required',
            'title' => 'required',
            'description' => 'required'
        ];
    }
}

tykus's avatar

What are you doing here?

auth()->user()->$topic//...

and here:

public function topics()
{
    return $this->hasManyThrough(Topic::class, User::class);
}

Also, the slug is not fillable on the Topic model.

1 like
Hiiro's avatar
Level 2

@tykus i tried to auth the user that will post the topics first

tykus's avatar

@Hiiro Okay... so it would not require you to new-up a Topic instance; user the relationship

auth()->user()->topics()->create([/*attributes*/ ]);

Now back to that relationship; why is it a hasManyThrough; surely a hasMany is what is needed???

public function topics()
{
    return $this->hasMany(Topic::class);
}

Should validation fail in the Form Request class; are you displaying the validation errors anywhere?

1 like
Hiiro's avatar
Level 2

@tykus i tried the relationship

auth()->user()->topics()->create([/*attributes*/ ]);

but it show that

Undefined method 'topics'.intelephense(1013)
tykus's avatar

@Hiiro if you want intelephense to be happy; either install Laravel IDE Helper, or :

/** @var \App\Models\User */
$user = auth()->user();
$user->topics()->create([/*attributes*/ ]);
1 like
Hiiro's avatar
Level 2

@tykus its still showing the same like before

Undefined method 'topics'.intelephense(1013)

Sinnbeck's avatar

You dont have a form in that view?? Is that endpoint a GET request?

Hiiro's avatar
Level 2

@Sinnbeck i have on topics.create

@extends('layout/main')


@section('title','Forum - Create Discussions')




@section('container')
<div class="container">
    <br>
    <div class="row justify-content-center">
        <div class="col-md-15">

            <div class="card">
                <div class="card-header">{{ __('Add Discussions ') }}</div>

                <div class="card-body">
                    <form action="{{route('topic.store')}}" method="POST">
                        @csrf
                        <div class=form-group>
                            <label for="genre">Genre</label>
                            <br>
                            <select name="genre" id="genre" class="form-control">
                                @foreach($genres as $genre)
                                <option value="{{$genre->id}}">{{$genre->nama}}</option>
                                @endforeach
                            </select>
                        </div>
                        <br>
                        <div class="form-group">
                            <label for="floatingInput">Judul</label>
                            <br>
                            <input type="text" id="title" name="title" class="form-control" placeholder="Judul" required="required">
                        </div>
                        <br>
                        <div class="form-group">
                            <label for="description">Description</label>
                            <br>
                            <input id="description" type="hidden" name="description">
                            <trix-editor input="description"></trix-editor>
                        </div>

                        <br>
                        <button type="submit" class="btn btn-success">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    @endsection

    @section('css')
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/trix/1.3.1/trix.css">
    @endsection

    @section ('js')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/trix/1.3.1/trix.js">

    </script>
    @endsection
tykus's avatar

@Hiiro no validation errors being displayed; e.g.

<div class="form-group">
    <label for="floatingInput">Judul</label>
    <br>
    <input type="text" id="title" name="title" class="form-control" placeholder="Judul" required="required">
	@error('title')
        <div class="alert alert-danger">{{ $message }}</div>
    @enderror
</div>
1 like
Hiiro's avatar
Level 2

@tykus what should i do after that?

first, i'm sorry, i'm new to laravel, i just following tutorial from yt

tykus's avatar

@hiiro where are you at right now with

  • the Controller action (code?)
  • the topics relationship on the User model (code?)
  • displaying validation errors
  • making the slug fillable?
1 like
Hiiro's avatar
Level 2

@tykus

  • For Controller :
<?php

namespace App\Http\Controllers;

use App\Http\Requests\CreateTopicRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Models\Topic;
use App\Models\User;

class TopicController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth')->only(['create', 'store']);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */

    public function index()
    {
        return view('topics.index', [
            'topics' => Topic::paginate(5)
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('topics.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(CreateTopicRequest $request)
    {
        auth()->user()->topics()->create([
            'genre' => $request->genre,
            'title' => $request->title,
            'slug' => Str::slug($request->title),
            'description' => $request->description
        ]);

        session()->flash('success', 'Discussion posted!');

        return redirect()->route('topic.index');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Topic $topic)
    {
        return view('topics.show', [
            'topic' => $topic

        ]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

  • topics relationship on the user model
 public function topics()
    {
        return $this->hasMany(Topic::class);
    }

  • where to displaying validation errors?
1 like
tykus's avatar

@Hiiro where to displaying validation errors? in the create view:

<form action="{{route('topic.store')}}" method="POST">
    @csrf
    <div class=form-group>
        <label for="genre">Genre</label>
        <br>
        <select name="genre" id="genre" class="form-control">
            @foreach($genres as $genre)
                <option value="{{$genre->id}}">{{$genre->nama}}</option>
            @endforeach
        </select>
	    @error('genre'')
            <div class="alert alert-danger">{{ $message }}</div>
        @enderror
    </div>
    <br>
    <div class="form-group">
        <label for="floatingInput">Judul</label>
        <br>
        <input type="text" id="title" name="title" class="form-control" placeholder="Judul" required="required">
	    @error('title')
            <div class="alert alert-danger">{{ $message }}</div>
        @enderror
    </div>
    <br>
    <div class="form-group">
        <label for="description">Description</label>
        <br>
        <input id="description" type="hidden" name="description">
        <trix-editor input="description"></trix-editor>
	    @error('description')
            <div class="alert alert-danger">{{ $message }}</div>
        @enderror
    </div>

    <br>
    <button type="submit" class="btn btn-success">Submit</button>
</form>

Is the column really called genre and not the conventional genre_id???

I am supposing that there is a validation error; and since you are not displaying them, it appears to fail silently.

1 like
Hiiro's avatar
Level 2

@tykus you mean by following same name on store?

-after i put the validation error, this appeared when i refresh

ParseError
syntax error, unexpected single-quoted string "];", expecting "]" (View: C:\xampp\htdocs\forumMusik\resources\views\topics\create.blade.php)

tykus's avatar
tykus
Best Answer
Level 104

@Hiiro typo

@error('genre')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror
2 likes
Hiiro's avatar
Level 2

@tykus okk

and this appear

The genre field is required.

what shoud i change?

tykus's avatar

@Hiiro okay, so there was a validation error. Where does the select element get its options? You don't pass anything from the create Controller action into the view:

    public function create()
    {
        return view('topics.create', ['genres' => Genre::all()]);
    }

Then, select a Genre option whenever you are submitting the form...

1 like
Hiiro's avatar
Level 2

@tykus okay, its still showing the same problem

i use 'genre' because name of the field is 'genre'

public function create()
    {
        return view('topics.create', ['genre' => Genre::all()]);
    }
tykus's avatar

@Hiiro you still get a validation error for genre whenever you select a something from that dropdown? Does the genres table have an id column?

1 like
Hiiro's avatar
Level 2

@tykus yes i still get a validation error..

yes genres table have an id column

tykus's avatar

@Hiiro can you check the page source in the browser and find the genre select element - post the HTML markup here.

Next, temporarily replace the CreateTopicRequest typehint with the default Request; and dump the contents of the Request

public function store(CreateTopicRequest $request)
{
    dd($request->all());
1 like
Hiiro's avatar
Level 2

@tykus i think its no need to do that

now its works!! thankyou @tykus , so for knowing what's the problem, we should put validation error on each div?

tykus's avatar

@Hiiro yes, if you don't actually display the validation errors, then it appears to silently fail; whereas whenever you do provide that feedback, it is clear where the issue arises.

If you're all set, please mark the thread closed.

1 like

Please or to participate in this conversation.