如何在数据库列中插入类型为string的数组?

I am having multiple checkboxes in my form, and when I select some of them and submit form I get error 'Array to string conversion'. My database column user_preferences is type string so that is the reason of error. I just don't know how to insert multiple values in that column. Any help is appreciated. Here is my code.

UserController.php

public function update(StoreUserInfo $request, User $user)
{
    //return $request->userPreferences;
    if ( !($user->id == Auth::user()->id)) {
        abort(404);
    }

    $request->validated();

    $user->where('id', $user->id)->update(
        [
            'first_name' => $request->first_name,
            'last_name' => $request->last_name,
            'email' => $request->email,
            'city' => $request->city,
            'type' => $request->type,
            'user_preferences' => $request->userPreferences,
            'updated_at' =>  Carbon::now()
        ]
    );
        return redirect()->back()->with('message', 'User information updated');
}

edit.blade.php

<div class="row page-hero d-flex align-items-center justify-content-center">
    <label for="preferences" class="text-center">Select your preferences</label>         
</div>
<div class="row">                
    <div class="col-md-1" style="margin-right:15px; margin-left:60px;">
        <div class="custom-control custom-checkbox">
            <input id="kuca" name="userPreferences[]" value="kuca" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="kuca">Kuca</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:15px;">
        <div class="custom-control custom-checkbox">
            <input id="stan" name="userPreferences[]" value="stan" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="stan">Stan</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:50px;">
        <div class="custom-control custom-checkbox">
            <input id="apartman" name="userPreferences[]" value="apartman" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="apartman">Apartman</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:15px;">
        <div class="custom-control custom-checkbox">
            <input id="soba" name="userPreferences[]" value="soba" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="soba">Soba</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:15px;">
        <div class="custom-control custom-checkbox">
            <input id="lokal" name="userPreferences[]" value="lokal" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="lokal">Lokal</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:15px;">
        <div class="custom-control custom-checkbox">
            <input id="plac" name="userPreferences[]" value="plac" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="plac">Plac</label>
        </div>
    </div>
    <div class="col-md-1" style="margin-right:15px;">
        <div class="custom-control custom-checkbox">
            <input id="garaza" name="userPreferences[]" value="garaza" type="checkbox" class="custom-control-input">
            <label class="custom-control-label" for="garaza">Garaza</label>
        </div>
    </div>           
</div>

You could use php implode() function to join the string array into one string like this:

$user->where('id', $user->id)->update(
    [
        'first_name' => $request->first_name,
        'last_name' => $request->last_name,
        'email' => $request->email,
        'city' => $request->city,
        'type' => $request->type,
        'user_preferences' => implode(',', $request->userPreferences),
        'updated_at' =>  Carbon::now()
    ]
);

https://php.net/implode

Then when you are displaying the values in your show.blade.php, you can then use $userPreferences = explode(',', $row->userPreferences); to get the array back.

https://php.net/explode

Use json_encode

You can encode in your Update Query or you cast the field in the Model.

You can use $casts property (https://laravel.com/docs/5.8/eloquent-mutators#array-and-json-casting):

class User extends Model
{

    protected $casts = [
        'user_preferences' => 'array',
    ];
}

By doing this, Laravel will automatically serialize array to JSON and vice versa.

You can implode the value with comma(,) separated and save the string.

For Example.

$preferences = implode(',',$request->userPreferences);
$user->where('id', $user->id)->update(
    [
        'first_name' => $request->first_name,
        'last_name' => $request->last_name,
        'email' => $request->email,
        'city' => $request->city,
        'type' => $request->type,
        'user_preferences' => $preferences,
        'updated_at' =>  Carbon::now()
    ]
);

I think the easiest solution is to store your value in JSON. There is a php function that allows you to encode and decode objects and arrays to JSON, namely json_encode and json_decode respectively.

In your case, you could simply change your update statement to:

$user->where('id', $user->id)->update(
        [
            'first_name' => $request->first_name,
            'last_name' => $request->last_name,
            'email' => $request->email,
            'city' => $request->city,
            'type' => $request->type,
            'user_preferences' => json_encode($request->userPreferences),
            'updated_at' =>  Carbon::now()
        ]
    );

When you get your data from the model, you need to decode the string back to an array. You can do that like this:

$user = User::find($user->id);
if ($user) {
    $preferences = json_decode($user->user_preferences);
}

As the other answers here stated, Laravel can automate this for you with Array & JSON Casting

You can Use json_encode function while inserting the data to database.

After that you can type cast in Users Model so that you will get normal array while fetching records. Add following function to User Model.

public funtion getUserPreferencesAttribute()
{
     return json_decode($this->attributes['user_preferences']);
}

If you are using Laravel and a more recent version of MySQL you may be better to create a field type JSON and cast it to an array in your eloquent model.

Then Laravel will automatically encode and decode the field for you.

It will also mean you can query the field by using model::where('preference->type', 'thing').

It may be possible to do this with a string field type but I'm not 100% on that but it will work with JSON.