5

In the Laravel documentation it says you can use this syntax for querying an object relation to get only the Posts that have at least one Comment:

$posts = Post::has('comments')->get();

I'm trying something similar where I want to fetch only objects that have at least one relation object. These are my two classes:

class Movie extends Eloquent {
    protected $table = 'movie';

    public function matches() {
        return $this->hasMany("Match");
    }
}

class Match extends Eloquent {
    protected $table = 'match';

    public function movie() {
        return $this->belongsTo("Movie");
    }
}

But when I call

$movies = Movie::has('matches')->get();

I get an empty collection. If I call

$movie = Movie::find(1)->matches()->get();

I do get the Match that relates to the Movie, so I know the relation is setup properly. I can't figure out what I'm doing wrong with the Movie::has method though.

I'm using the sqlite3 database included with a laravel project created with composer. This is the structure and data:

sqlite> .schema movie
CREATE TABLE "movie" ("id" integer not null primary key autoincrement, "title" varchar not null);

sqlite> .schema match
CREATE TABLE "match" ("id" integer not null primary key autoincrement, "movie_id" integer not null, "title" varchar not null, foreign key("movie_id") references "movie"("id"));
CREATE INDEX match_movie_id_index on "match" ("movie_id");

sqlite> select * from movie;
1|Test Movie

sqlite> select * from match;
1|1|Test Movie Match
tshepang
  • 12,111
  • 21
  • 91
  • 136
Mat
  • 187
  • 2
  • 10
  • Also, I can't see where the 'has' method comes from. The Model class doesn't have a 'has' method. – Mat Dec 27 '13 at 17:53
  • The method is described in the API Documentation: [here](http://laravel.com/api/master/Illuminate/Database/Eloquent/Builder.html#method_has) – The Sauralph Jan 21 '14 at 19:30
  • Did you figure out what the issue was? Seem to have the same problem. – Markus Feb 16 '14 at 21:42
  • Unfortunately not. It is a personal project so I haven't had a lot of time to debug it. I did start going through the Illuminate/Database/Eloquent/Builder::has method as The Sauralph pointed out, but in the return statement it calls $query->toSql() and the resulting SQL seems to be the problem. I'll try to look at it again tonight and post the SQL it generates. – Mat Feb 18 '14 at 15:07
  • I switched to MySQL and the problem is gone. I checked the queries that Laravel generates and they work fine in both MySQL and SQLite, so I'm still not sure why the result set is empty when using SQLite. – Mat Feb 22 '14 at 04:56

1 Answers1

6

This however works fine with the MySQL driver. When using SQLite as the database driver, has returns an empty collection because the count gets wrapped in quotes. You may use the DB::raw method to pass the count as a raw expression.

$posts = Post::has('comments', '>=', DB::raw(1))->get();

Related issues: #3353, #3435.

Edit: As patricus affirmed this issue was affecting only installations prior to Laravel 4.1.25. You don't need to use this workaround with newer versions.

Community
  • 1
  • 1
cdog
  • 2,054
  • 1
  • 18
  • 16
  • 1
    While this was true at the time, the issue has been fixed since version 4.1.25. Would you mind updating your answer to add in this information? No need to change the answer, since it is correct for this question, but adding an edit letting people know they don't need to do this anymore would be good. I was prompted to look into this because someone just posted a question with this syntax which they copied from this answer. – patricus Feb 18 '16 at 04:34