NoLAstNamE's avatar

Using create with conditional column to save

Let's take a look at this example, I have a store method that stores a post in the database.

public function store(PostStoreRequest $request): RedirectResponse
{
    $post = Post::create($request->validated());

    return redirect(route('posts.show', $post));
}

But what if I have an optional field that will only save if it's present in the request e.g. image?

The code I have for that is this, but PHPStorm is complaining that I'm accessing image_path, title, and content magically. And that is because accessing via magic methods is deprecated and will soon not be working.

public function store(PostStoreRequest $request): RedirectResponse
{
    $path = // do the upload thing here

    $post = new Post();
    if ($request->hasFile('image') {
        $post->image_path = $path;
    }
    $post->title = $request->input('title');
    $post->content = $request->input('content');
    $post->save()

    return redirect(route('posts.show', $post));
}

What is your approach in this kind of situation that still uses Post::create()?

0 likes
8 replies
LaryAI's avatar
Level 58

You can use the fill method to set the attributes of the model before saving it. This way you can conditionally set the image_path attribute if the request has a file.

public function store(PostStoreRequest $request): RedirectResponse
{
    $post = new Post();
    $post->fill($request->validated());

    if ($request->hasFile('image') {
        $path = // do the upload thing here
        $post->image_path = $path;
    }

    $post->save()

    return redirect(route('posts.show', $post));
}
NoLAstNamE's avatar

@LaryAI Thanks Lary the #AI, but I think this is not the answer that I'm looking for.

jlrdw's avatar

@benjamin1509 what do you want to store? Myself, if there is no image then I store null in the field.

1 like
NoLAstNamE's avatar

@jlrdw I want to store a post, and image by using Post::create.

I don't like this approach because PHPStorm is complaining about it.

public function store(PostStoreRequest $request): RedirectResponse
{
    $path = // do the upload thing here

    $post = new Post();
    if ($request->hasFile('image') {
        $post->image_path = $path;
    }
    $post->title = $request->input('title');
    $post->content = $request->input('content');
    $post->save()

    return redirect(route('posts.show', $post));
}
tykus's avatar
tykus
Best Answer
Level 104

@benjamin1509 any number of ways you can achieve this, e.g.

public function store(PostStoreRequest $request): RedirectResponse
{
    $attributes = $request->safe();

    if ($request->hasFile('image')) {
        // handle file upload and get the `$path
        $attributes['path'] = $path;
    }

    $post = Post::create($attributes);
    return redirect(route('posts.show', $post));
}
1 like
NoLAstNamE's avatar

@tykus Thank you! one question is this also one of the best practices? I want to always go with the best practices so I'm ready when I got a job. I can confidently say that I follow best practices.

TIL: $request->safe()

tykus's avatar

@benjamin1509 best practices is subjective and different developers will have their preferred approach. However, this is an officially documented approach to handling validated input.

1 like

Please or to participate in this conversation.