Laravel using UNION in query builder

11,621

Solution 1

Looks like your models are using Ardent, not Eloquent:

...instance of LaravelBook\Ardent\Builder given, ...

And probably this might be a problem on Ardent, not Laravel.

Open an issue here: https://github.com/laravelbook/ardent.

EDIT:

Try to change use QueryBuilder instead of Eloquent:

Use this for QueryBuilder:

DB::table('tags')->

Instead of the Eloquent way:

Tag::

Solution 2

I know you mentioned wanting to use the query builder, but for complex queries that the builder might throw fits on, you can directly access the PDO object:

$pdo = DB::connection()->getPdo();
Share:
11,621
Al_
Author by

Al_

gfdsgd

Updated on June 04, 2022

Comments

  • Al_
    Al_ almost 2 years

    I have an SQL query that works fine and I'm trying to convert into fluent::

    SELECT DISTINCT tags.tag
      FROM tags, items
      WHERE tags.taggable_type = 'Item'
      AND items.item_list_id = '1'
    UNION
    SELECT DISTINCT tags.tag
      FROM tags, itemlists
      WHERE tags.taggable_type = 'ItemList'
      AND itemlists.id = '1'
    

    This is what I have so far in fluent, it all seems right as far as I can tell from the docs and the individual queries both work on their own, it's just when I UNION them it throws an error:

       $itemTags = Tag::join('items', 'items.id', '=', 'tags.taggable_id')
                    ->select('tags.tag')
                    ->distinct()
                    ->where('tags.taggable_type', '=', 'Item')
                    ->where('items.item_list_id', '=', $itemList->id);
    
        $itemListTags = Tag::join('itemlists', 'itemlists.id', '=', 'tags.taggable_id')
                    ->select('tags.tag')
                    ->distinct()
                    ->where('tags.taggable_type', '=', 'ItemList')
                    ->where('itemlists.id', '=', $itemList->id);
    // the var_dump below shows the expected results for the individual queries
    // var_dump($itemTags->lists('tag'), $itemListTags->lists('tag')); exit;
        return      $itemTags
                    ->union($itemListTags)
                    ->get();
    

    I get the following error when I run it (I've also swapped from Ardent back to Eloquent on the model in case that made a difference - it doesn't):

    Argument 1 passed to Illuminate\Database\Query\Builder::mergeBindings() must be an instance of Illuminate\Database\Query\Builder, instance of LaravelBook\Ardent\Builder given, called in path/to/root\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php on line 898 and defined 
    
  • Al_
    Al_ over 10 years
    Hi, I've tried setting all three models to extend Eloquent not Ardent I I get a similar error: Argument 1 passed to Illuminate\Database\Query\Builder::mergeBindings() must be an instance of Illuminate\Database\Query\Builder, instance of Illuminate\Database\Eloquent\Builder given, called in E:\docs\Documents\Work\MGC\mgc_root\vendor\laravel\framework‌​\src\Illuminate\Data‌​base\Query\Builder.p‌​hp on line 898 and defined
  • Antonio Carlos Ribeiro
    Antonio Carlos Ribeiro over 10 years
    Are you using Laravel 4.0 or 4.1?
  • Al_
    Al_ over 10 years
    4.0 I believe, I'll try running a composer update to see if that helps
  • Antonio Carlos Ribeiro
    Antonio Carlos Ribeiro over 10 years
    Edited, might work using QueryBuilder. But this looks like a bug on Laravel.
  • Al_
    Al_ over 10 years
    I'm on 4.0 the composer.json file has : "laravel/framework": "4.0.*",, I've run a composer update. Guess I'll file a bug report, thanks.
  • Antonio Carlos Ribeiro
    Antonio Carlos Ribeiro over 10 years
    Did you saw my edit? Tested using QueryBuilder instead of Eloquent?
  • Al_
    Al_ over 10 years
    Hi, just noticed it. That does seem to work - strange! Is that a bug that should be reported do you think or should I close the bug request I opened on github. Thanks!!
  • Antonio Carlos Ribeiro
    Antonio Carlos Ribeiro over 10 years
    Keep it. There's a problem on Eloquen/QueryBuilder.
  • Antonio Carlos Ribeiro
    Antonio Carlos Ribeiro over 10 years
    No problem. Enjoy Laravel! :)
  • lu cip
    lu cip over 10 years
    I got the same issue, anyway this is because mergeBindings() function expect an instance of Illuminate\Database\Query\Builder instead of Ardent\Builder or Eloquent\Builder... as you said before. So DB::table('tags') can replace Tag just for variable $itemListTags sent to union() function. I said that because sometimes (as in my case) you need Eloquent or Ardent for the first object ( as $itemTags in this case ), and this can stay Eloquent or Ardent. Thanks for your answer.