0

I'm currently working on a blog in Laravel 8.

The Article model is made like this:

protected $fillable = [
        'title',
        'subtitle',
        'body',
        'category',
        'view_count',
        'published_at',
        'tags'
    ];

protected $casts = [
        'published_at' => 'date:d-m-Y',
        'tags' => 'array'
    ];

I'd like to index my Article model, to make it searchable by title, subtitle, body and tags (which is the field that gives my problems).

For searching, I'm using Laravel Scout with TNTSearch. My toSearchableArray() function is the following:

public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'title' => $this->title,
            'subtitle' => $this->subtitle,
            'body' => $this->body,
            'tags' => $this->tags
        ];

        return $array;
    }

The problem is that when I launch php artisan scout:import "App\Models\Article" I receive this error:

mb_strtolower(): Argument #1 ($string) must be of type string, array given

  at C:\Users\Davide\working_area_davide\Freelance\sito_alvise_L8\vendor\teamtnt\tntsearch\src\Support\Tokenizer.php:10
      6▕     static protected $pattern = '/[^\p{L}\p{N}\p{Pc}\p{Pd}@]+/u';
      7▕
      8▕     public function tokenize($text, $stopwords = [])
      9▕     {
  ➜  10▕         $text  = mb_strtolower($text);
     11▕         $split = preg_split($this->getPattern(), $text, -1, PREG_SPLIT_NO_EMPTY);
     12▕         return array_diff($split, $stopwords);
     13▕     }
     14▕ }

So I tried to transform $this->tags in a string, like this:

public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'title' => $this->title,
            'subtitle' => $this->subtitle,
            'body' => $this->body,
            'tags' => implode(',', $this->tags),
        ];

        return $array;
    }

but then I receive this error:

 implode(): Argument #1 ($pieces) must be of type array, string given

  at C:\Users\Davide\working_area_davide\Freelance\sito_alvise_L8\app\Models\Article.php:38
     34▕             'id' => $this->id,
     35▕             'title' => $this->title,
     36▕             'subtitle' => $this->subtitle,
     37▕             'body' => $this->body,
  ➜  38▕             'tags' => implode(',', $this->tags),
     39▕         ];
     40▕
     41▕         return $array;
     42▕     }

I searched the internet for a solution but didn't find anything.

Hope that someone can help! Thanks in advance!

rx4storm
  • 1
  • 1

2 Answers2

0

Would something like this work?

    public function toSearchableArray()
    {
        $tags = $this->tags;

        if (is_array($tags)) {
            $tags = implode(',', $this->tags);
        }
        
        $array = [
            'id'       => $this->id,
            'title'    => $this->title,
            'subtitle' => $this->subtitle,
            'body'     => $this->body,
            'tags'     => $tags
        ];

        return $array;
    }
Nenad
  • 3,438
  • 3
  • 28
  • 36
0

I solved by undoing the array casting in protected $casts.

Honestly I don't know why, but that's that.

rx4storm
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 20 '22 at 07:54