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

martincodes's avatar

Create with default relationship values

Hey i need your help. I want to add a report that after creation will directly get the status, category and edit category with ID 1. However, I can't get it to work. The report has the relationships to each status, category and editor category.

When I create a report, how can I give it default values for its relationship?

Report Model:

class Report extends Model
{
    use HasFactory;

    protected $fillable = [
      "kategorie_id",
      "absender_name",
      "absender_persoid",
      "absender_mail",
      "absender_handynummer",
        "anhang_url",
        "inhalt",
        "bearbeiterkategorie_id",
        "bearbeiter_name",
        "bearbeiter_notiz",
        "status_id"
    ];

    public function status() {
        return $this->hasOne(Status::class, "id");
    }

    public function kategorie() {
        return $this->hasOne(Kategorie::class, "id");
    }

    public function bearbeiterkategorie() {
        return $this->hasOne(Bearbeiterkategorie::class, "id");
    }
}

Editorcategory Model:

class Bearbeiterkategorie extends Model
{
    use HasFactory;

    protected $fillable = [
      "name",
      "beschreibung"
    ];

    public function report() {
        return $this->belongsTo(Report::class);
    }
}

Status Model:

class Status extends Model
{
    use HasFactory;

    protected $fillable = [
        "name",
        "beschreibung",
        "badgefarbe"
    ];

    public function report() {
        return $this->belongsTo(Report::class);
    }
}

Category Model:

class Kategorie extends Model
{
    use HasFactory;

    protected $fillable = [
        "name",
        "beschreibung"
    ];

    public function report() {
        return $this->belongsTo(Report::class);
    }
}

Reportcontroller@store

public function store(Request $request)
    {
        $this->validate($request, [
           "absender_name" => "required",
            "absender_persoid" => "required|integer|min:1",
            "absender_mail" => "required",
            "absender_handynummer" => "required|numeric",
            "kategorie_id" => "required|exists:kategories,id",
            "inhalt" => "required",
            "anhang_url" => "nullable|active_url"
        ]);

        Report::create([
            "kategorie_id" => $request->kategorie_id,
            "absender_persoid" => $request->absender_persoid,
            "absender_name" => $request->absender_name,
            "absender_mail" => $request->absender_mail,
            "absender_handynummer" => $request->absender_handynummer,
            "anhang_url" => $request->anhang_url,
            "inhalt" => $request->inhalt
        ]);

        return back()->with("success", "Ihre Meldung wurde erfolgreich an das Los Santos Police Department eingereicht.");
    }

Reports-Migration

public function up()
    {
        Schema::create('reports', function (Blueprint $table) {
            $table->id();
            $table->foreignId("kategorie_id")->constrained();
            $table->string("absender_persoid");
            $table->string("absender_name");
            $table->string("absender_mail");
            $table->string("absender_handynummer");
            $table->string("anhang_url")->default(" ");
            $table->longText("inhalt");
            $table->foreignId("bearbeiterkategorie_id")->constrained();
            $table->string("bearbeiter_name")->default("Kein Bearbeiter");
            $table->longText("bearbeiter_notiz")->default("");
            $table->foreignId("status_id")->constrained();
            $table->timestamps();
        });
    }

0 likes
5 replies
guybrush_threepwood's avatar

Hi @martincodes

        Report::create([
            "kategorie_id" => 1,
            "status_id" => 1,
            "bearbeiterkategorie_id" => 1,
            "absender_persoid" => $request->absender_persoid,
            "absender_name" => $request->absender_name,
            "absender_mail" => $request->absender_mail,
            "absender_handynummer" => $request->absender_handynummer,
            "anhang_url" => $request->anhang_url,
            "inhalt" => $request->inhalt
        ]);

You could also set them a defaults in your Report model:

protected $attributes = [
        'kategorie_id' => 1,
        'status_id' => 1,
        'bearbeiterkategorie_id' => 1,
];

I'd also recommend using constants instead of magic numbers to make the code more readable.

martincodes's avatar

If i do this with the attributes solution, this is the error message on the output site:

Trying to get property 'name' of non-object (View: D:\XAMPP\htdocs\lspdrsys-git\lspdrsys-git\resources\views\home.blade.php)

<table class="table table-bordered">
                <tr>
                    <th>ID</th>
                    <th>Kategorie</th>
                    <th>Absender-ID</th>
                    <th>Absender-Name</th>
                    <th>Absender-Email</th>
                    <th>Absender-Handynr.</th>
                    <th>Anhang-URL</th>
                    <th>Zugeteilt zu</th>
                    <th>Bearbeiter</th>
                    <th>Status</th>
                    <th>Eingegangen am</th>
                    <th>Zuletzt bearbeitet am</th>
                </tr>
                @foreach($reports as $report)
                <tr>
                    <td>{{$report->id}}</td>
                    <td>{{$report->kategorie->name}}</td>
                    <td>{{$report->absender_persoid}}</td>
                    <td>{{$report->absender_name}}</td>
                    <td>{{$report->absender_mail}}</td>
                    <td>{{$report->absender_handynummer}}</td>
                    @if($report->anhang_url != "")
                        <td>{{$report->anhang_url}}</td>
                    @else
                        <td>Kein Anhang vorhanden.</td>
                    @endif
                    <td>{{$report->bearbeiterkategorie->name}}</td>
                    <td>{{$report->bearbeiter_name}}</td>
                    <td><span class="badge badge-{{$report->status->badgefarbe}}">{{$report->status->name}}</span></td>
                    <td>{{$report->created_at}}</td>
                    <td>{{$report->updated_at}}</td>
                </tr>
                @endforeach

Controller:

/**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home', [
            "reports" => Report::all()
        ]);
    }

guybrush_threepwood's avatar
Level 33

I see the problem, it's unrelated to the original question. You've set up your relationships as one-to-one instead of one-to-many.

Change your Report model relationships to:

class Report extends Model
{
    // ...

    public function status() {
        return $this->belongsTo(Status::class);
    }

    public function kategorie() {
        return $this->belongsTo(Kategorie::class);
    }

    public function bearbeiterkategorie() {
        return $this->belongsTo(Bearbeiterkategorie::class);
    }
}

And on the rest of your models:

    public function report() {
        return $this->hasMany(Report::class);
    }
1 like
martincodes's avatar

Okay - but why? A report has a status, a category and an editor category. I have to admit that I haven't really understood the relationships yet. Do you have a good tutorial/explanation? The documentation doesn't help me much.

guybrush_threepwood's avatar

Here's a good series on the subject: https://laracasts.com/series/eloquent-relationships

Think of it like this:

Can a specific report belong to many different statuses? No

Can a status have many reports assigned? Yes

Then you have a one to many relationship. Check Laravels docs on how to handle the relationship/inverse relationship in such cases.

1 like

Please or to participate in this conversation.