Home > Software design >  Custom search that look for part of a string inside values of a model and its relationship (one to m
Custom search that look for part of a string inside values of a model and its relationship (one to m

Time:11-28

I have a search input text that uses ajax to search for some articles (article is a model). Also, I have made a relationship one-to-many with another model "ArticleFile". Essentially, I need to look if there's a value that contains a string in the columns "title" or "description" of the article table OR (that's the hardest part) inside the column filename from the article file table with a column article_id. Since many articles contains a list of files attached to it, is there a way to search if the article's title, description or the filenames attached to it have a certain string that resembles my code? Or is there another way to achieve this?

Relationship one-to-many inside my Article model:

public function files() {
   return $this->hasMany(ArticleFile::class);
}

In my php file from the ajax call, I have the following method to retrieve the right articles (which doesn't work):

public function ajax_article_search()
{
  $value = $_POST['value'];
  $html = '';

  if($value) {
    
    // search if the title
    // or description
    // or filenames (of the relationship one-to-many)
    // have a certain $value
    $articles = Article::where('title', 'like', '%'.$value.'%') 
      ->orWhere('description', 'like', '%'.$value.'%') 
      ->files->where('filename', 'like', '%'.$value.'%') 
      ->get(); 
    
    // -- Code above not working
    // Error because of ->files...
        
    foreach($articles as $article) {
      $html .= '<a href="'.$article->url.'">';
      $html .= '<p>'.$article->title.'</p>';
      $html .= '</a>';
    }
  }

  echo $html;
}

CodePudding user response:

For querying against a relationship, you can use whereHas() (or in this case orWhereHas()):

$articles = Article::where('title', 'like', '%'.$value.'%')
    ->orWhere('description', 'like', '%'.$value.'%')
    ->orWhereHas('files', function ($query) use($value) {
        $query->where('filename', 'like', '%'.$value.'%');
    })
    ->get(); 
  • Related