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

davidebo's avatar

how to add an array in a database

i would like to insert related posts in a column of my post table called 'correlated_posts'. in the store method of controller i have this and i've done the casts in the model protected $casts = [ 'correlated_posts' => 'array', ]; and in database the column is type string

i receive always null result, does someone know why ?

        $post->author = $request->input('author');
        $post->article = $request->input('post_html');
        $post->summary = $request->input('summary');

        if(!empty($request->correlated_posts)){
   			  $correlated_posts=  $request->input('correlated_posts');
            $post->correlated_posts = $correlated_posts;
	}

$correlated_posts is like this 
array:3 [▼
  0 => "1"
  1 => "2"
  2 => "4"
] ```
0 likes
32 replies
davidebo's avatar

understood, but i didn't want to do a pivot table

webrobert's avatar

@davidebo, it seems like a good idea now. But 99% of the time it's not. You loose more than you gain. The work you are avoiding now will cascade into extra work when you want to interact with that data that is bound up in a columns.

Sinnbeck's avatar

@davidebo so you are absolutely sure you will never ever need to query that data? If you ever need to find out which posts a post is correlated to, then what?

Anyways please format your code by adding ``` on the line before and after it. After that I will take a look at it

Sinnbeck's avatar

Where do you get null? In the database? Or dd()?

davidebo's avatar

well, here the user when create a new post have to choose at maximum 3 correlated posts for that post, if he choose 1 the others 2 are random and if he choose 2 the other is random, maybe is better with pivot,

Sinnbeck's avatar

@davidebo I would go with pivot at least. That way you can add a column to indicate which are chosen by the user :)

CamKem's avatar

@Sinnbeck Is there any benefit of using a pivot table over having a seperate model & migration for correlated_posts?

It would seem there is a lot of advantages with eloquent relationships in having the correlated_posts data stored in a seperate migration so the data is not nested inside a json column in the table.

davidebo's avatar

@Sinnbeck so you are suggensting to create a pivot table between the posts and the user, for example a post_user table where there are these column : id, post_id, correlated_post and the user_id ?

Sinnbeck's avatar

@davidebo you can in theory call it what you want. You just need to specify it in the relationship then. But I would imagine you just need post_id, user_id and user_added? No need for id and no need for two posts columns?

Or is it a related relationship between two posts? If so, yours is fine 👍 (no need for id though)

davidebo's avatar

@Sinnbeck the user will be only one here, but when create the post have to choose 1-3 posts, from his choice

Sinnbeck's avatar

@davidebo ok so it's related posts for the post they are creating? Then yes your columns should be fine :) but no need for a user_id in theory as the main post already has a user_id I assume. So post_id and related post_id

davidebo's avatar

@Sinnbeck yes are related posts for the post they are creating, but if the pivot connect two tables, for example posts and users, in the pivot doesn't need to exists user_id ? even if in posts table i have already the user_id

    Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users');
CamKem's avatar

@davidebo You could consider keeping the user_id table & making it nullable, so that you can use it for logic that tells if the post was user added & also the id of the user that added the post. As you need at least a Boolean for checking if it’s user added, then you could store the user_id too?

1 like
Sinnbeck's avatar

@davidebo sorry if it wasn't clear but exactly. No need for user_id on the pivot. You can add it if you want, but it isn't needed

MohamedTammam's avatar

As people here mentioned, you it's better to add pivot table. But for the 1% use case I will write how to add array to your database.

First the column should be JSON or Text, it might also be String if the array is always short.

Secondly, in your Laravel model you should case your column to JSON

class Post extends Model
{
    protected $casts = [
        'correlated_posts' => 'array',
    ];
}

https://laravel.com/docs/9.x/eloquent-mutators#array-and-json-casting

2 likes
Ben Taylor's avatar

I would only ever use the array approach if I was 100% certain I would never ever need to query by it. Your case seems very likely to require a query.

1 like
Tray2's avatar

Like so many other here are suggesting, use a pivot for this, it makes it much easier to do all the crud operations you will need. It is also much faster when it comes to filtering on those posts, since they can be indexed. An json column can't be, without simulating a virtual table for each of the "columns" in the array.

1 like
davidebo's avatar

@Tray2 and how should be a manyToMany relation with just a post table and the correlated posts as pivot ? i mean, the user can choose maximum 3 posts of his choice, so every post should have 3 related posts

davidebo's avatar

@Tray2 yes ok, but I do not understand how should be the other table for relation, i have a post table like this, and the one for correlated posts should have an id, the post_id and the related posts for every post_id ?

Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title',128)->index('idx_title')->unique();
            $table->foreignId('user_id')->constrained('users');
            $table->string('author');
            $table->text('article');
            $table->text('summary')->nullable();
            $table->string('post_thumb',128)->nullable();
            $table->string('meta_title')->nullable();
            $table->string('meta_description')->nullable();
            $table->string('slug')->unique();
CamKem's avatar

@Tray2 I’m interested in pivot tables, can you help me understand why you would use them over creating a seperate migration & model for related_posts (with user_id & post_id), then use eloquent to set up the relationships?

Sinnbeck's avatar

@CamKem that's what a pivot table is. So let's say you need to connect users with posts, you would make a table named post_user. Pivot is for when both parts had many. So a user has many posts and a post has many users

davidebo's avatar

@webrobert yes, i didn't know which tables connect, but now is clear thanks, i will connect posts table with users table and in the pivot i will have the post_id and the post_correlated_id

1 like
Tray2's avatar

@davidebo Your pivot should contain post_id and corelated_post_id.

Let's look at you posts table.

Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title',128)->index('idx_title')->unique();
            $table->foreignId('user_id')->constrained('users');
            $table->string('author');
            $table->text('article');
            $table->text('summary')->nullable();
            $table->string('post_thumb',128)->nullable();
            $table->string('meta_title')->nullable();
            $table->string('meta_description')->nullable();
            $table->string('slug')->unique();

There isn't really any need to limit the size of the title to 128 characters, and adding a unique index is really bad, use a normal index instead, since the posts titles uniqueness should not be forced. Why do you have the author in the table, isn't the user_id the author? There is no need to store it twice.

1 like
davidebo's avatar

@Tray2 yes you are right, for the author well maybe wil be inserted another name, for the pivot connection i've done like this

class Post extends Model{
  public function correlatedPosts()
    {
        return $this->belongsToMany(Post::class, 'correlated_posts', 'post_id', 'correlated_post_id' )->withTimestamps();
    }
}

class CorrelatedPost extends Model{
 protected $table = "correlated_posts";

    public function post()
    {
        return $this->belongsToMany(Post::class, 'correlated_posts', 'correlated_post_id', 'post_id')->withTimestamps();
    }
}

class CreateCorrelatedPostsTable extends Migration
 public function up()
    {
        Schema::create('correlated_posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('post_id');
            $table->foreign('post_id')->on('posts')->references('id')->onDelete('cascade');
            $table->string('correlated_post_id');
            $table->timestamps();
        });
    }
}

class PostController extends Controller
{
public function store(Post $post, PostRequest $request, Tag $tag){
...  
$res = $post->save();
        if($request->has('correlated_posts')){
            $post->correlatedPosts()->syncWithPivotValues($request->input('correlated_posts'),['post_id' => $post->id ]);
        }
}
}

Please or to participate in this conversation.