Repository: statamic/eloquent-driver (php)

Issue:
Where on join query with alias not work
# Where on join query with alias not work
When a where clause apply on join query with alias, it cannot parse the correct where.

Let us consider the following query.  

__PHP Query__
```PHP
$query = Entry::query()
  // join self as e
  ->join('entries as e',fn($join) => $join
  ->whereColumn('e.id', 'entries.id')
  ->where('e.collection', 'properties')
  ->where('e.published', 1)
);
// join locations
$query->leftJoin('entries as locations', function($join) {
    $join
        ->where('locations.collection', 'locations')
        ->on('locations.id', 'e.data->location')
        ;
});
// where on joint clause
$query
  // this is expected to search on the JSON data field for property_type
  ->where('e.data->property_type', 'lodge')
  // this is expected to search on the locations slug for value 'shaldon'
  ->where('locations.slug', 'shaldon')
;
```

__SQL Generated__

The where property_type putting the e.data in the json key field but not the data field
```SQL
select * from `entries`
  inner join `entries` as `e`
    on `e`.`id` = `entries`.`id` and `e`.`collection` = 'properties' and `e`.`published` = '1'
  left join `entries` as `locations`
    on `locations`.`collection` = 'locations' and `locations`.`id` = json_unquote(json_extract(`e`.`data`, '$."location"'))
  where
    json_unquote(json_extract(`data`, '$."e.data"."property_type"')) = 'lodge' // Wrong SQL
    and json_unquote(json_extract(`data`, '$."locations.slug"')) = 'shaldon' // Wrong SQL
```
__SQL Expected__
```SQL
select * from `entries`
  inner join `entries` as `e`
    on `e`.`id` = `entries`.`id` and `e`.`collection` = 'properties' and `e`.`published` = '1'
  left join `entries` as `locations`
    on `locations`.`collection` = 'locations' and `locations`.`id` = json_unquote(json_extract(`e`.`data`, '$."location"')) 
  where
    json_unquote(json_extract(`e`.`data`, '$."property_type"')) = 'lodge' // SQL expected
    and `locations`.`slug` = 'shaldon' // SQL expected
```
## Cause
The problem caused by the column check in `src/Entries/EntryQueryBuilder.php`.

```PHP
protected function column($column)
{
    if ($column == 'origin') {
        $column = 'origin_id';
    }

    if (! in_array($column, self::COLUMNS)) {
        $column = 'data->'.$column;
    } else {
        $column = parent::column($column);
    }

    return $column;
}
```

Pull request:
Fix table name usage in clauses
Fixes #55 

Patch:
diff --git a/composer.json b/composer.json
index 5a0b78b..3de563f 100644
--- a/composer.json
+++ b/composer.json
@@ -24,7 +24,7 @@
     },
     "require": {
         "php": "^8.0",
-        "statamic/cms": "^3.3.31"
+        "statamic/cms": "^3.3.51"
     },
     "require-dev": {
         "doctrine/dbal": "^3.3",
diff --git a/database/migrations/create_asset_containers_table.php.stub b/database/migrations/create_asset_containers_table.php.stub
index ba1de19..589f43c 100644
--- a/database/migrations/create_asset_containers_table.php.stub
+++ b/database/migrations/create_asset_containers_table.php.stub
@@ -12,7 +12,7 @@ return new class extends Migration {
             $table->string('handle')->unique();
             $table->string('title');
             $table->string('disk');
-            $table->json('settings')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_asset_table.php.stub b/database/migrations/create_asset_table.php.stub
index eaedcc9..68ebfb6 100644
--- a/database/migrations/create_asset_table.php.stub
+++ b/database/migrations/create_asset_table.php.stub
@@ -10,7 +10,7 @@ return new class extends Migration {
         Schema::create($this->prefix('assets_meta'), function (Blueprint $table) {
             $table->id();
             $table->string('handle')->index();
-            $table->json('data')->nullable();
+            $table->jsonb('data')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_blueprints_table.php.stub b/database/migrations/create_blueprints_table.php.stub
index c2bf063..19ef555 100644
--- a/database/migrations/create_blueprints_table.php.stub
+++ b/database/migrations/create_blueprints_table.php.stub
@@ -12,7 +12,7 @@ return new class extends Migration {
             $table->id();
             $table->string('namespace')->nullable()->default(null)->index();
             $table->string('handle');
-            $table->json('data');
+            $table->jsonb('data');
             $table->timestamps();
 
             $table->unique(['handle', 'namespace']);
diff --git a/database/migrations/create_collections_table.php.stub b/database/migrations/create_collections_table.php.stub
index b39bf13..b7f953c 100644
--- a/database/migrations/create_collections_table.php.stub
+++ b/database/migrations/create_collections_table.php.stub
@@ -11,7 +11,7 @@ return new class extends Migration {
             $table->id();
             $table->string('handle')->unique();
             $table->string('title');
-            $table->json('settings')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_entries_table.php.stub b/database/migrations/create_entries_table.php.stub
index 850ebb4..7bbc589 100644
--- a/database/migrations/create_entries_table.php.stub
+++ b/database/migrations/create_entries_table.php.stub
@@ -16,8 +16,9 @@ return new class extends Migration {
             $table->string('slug')->nullable();
             $table->string('uri')->nullable()->index();
             $table->string('date')->nullable();
+            $table->integer('order')->nullable();
             $table->string('collection')->index();
-            $table->json('data');
+            $table->jsonb('data');
             $table->timestamps();
 
             $table->foreign('origin_id')
diff --git a/database/migrations/create_entries_table_with_string_ids.php.stub b/database/migrations/create_entries_table_with_string_ids.php.stub
index c14c990..1b079c0 100644
--- a/database/migrations/create_entries_table_with_string_ids.php.stub
+++ b/database/migrations/create_entries_table_with_string_ids.php.stub
@@ -16,8 +16,9 @@ return new class extends Migration {
             $table->string('slug')->nullable();
             $table->string('uri')->nullable()->index();
             $table->string('date')->nullable();
+            $table->integer('order')->nullable();
             $table->string('collection')->index();
-            $table->json('data');
+            $table->jsonb('data');
             $table->timestamps();
 
             $table->primary('id');
diff --git a/database/migrations/create_fieldsets_table.php.stub b/database/migrations/create_fieldsets_table.php.stub
index 4864639..e20dc1b 100644
--- a/database/migrations/create_fieldsets_table.php.stub
+++ b/database/migrations/create_fieldsets_table.php.stub
@@ -10,7 +10,7 @@ return new class extends Migration {
         Schema::create($this->prefix('fieldsets'), function (Blueprint $table) {
             $table->id();
             $table->string('handle')->unique();
-            $table->json('data');
+            $table->jsonb('data');
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_form_submissions_table.php.stub b/database/migrations/create_form_submissions_table.php.stub
index e9b6ba5..1487dcc 100644
--- a/database/migrations/create_form_submissions_table.php.stub
+++ b/database/migrations/create_form_submissions_table.php.stub
@@ -10,7 +10,7 @@ return new class extends Migration {
         Schema::create($this->prefix('form_submissions'), function (Blueprint $table) {
             $table->id();
             $table->foreignId('form_id')->constrained($this->prefix('forms'))->cascadeOnDelete();
-            $table->json('data')->nullable();
+            $table->jsonb('data')->nullable();
             $table->timestamps(6);
 
             $table->unique(['form_id', 'created_at']);
diff --git a/database/migrations/create_forms_table.php.stub b/database/migrations/create_forms_table.php.stub
index e58e1f3..cee7020 100644
--- a/database/migrations/create_forms_table.php.stub
+++ b/database/migrations/create_forms_table.php.stub
@@ -11,7 +11,7 @@ return new class extends Migration {
             $table->id();
             $table->string('handle')->unique();
             $table->string('title');
-            $table->json('settings')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_globals_table.php.stub b/database/migrations/create_globals_table.php.stub
index d31ba7c..aeed0b0 100644
--- a/database/migrations/create_globals_table.php.stub
+++ b/database/migrations/create_globals_table.php.stub
@@ -11,7 +11,7 @@ return new class extends Migration {
             $table->id();
             $table->string('handle')->unique();
             $table->string('title');
-            $table->json('localizations');
+            $table->jsonb('localizations');
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_navigation_trees_table.php.stub b/database/migrations/create_navigation_trees_table.php.stub
index 5b95424..bc0ec4e 100644
--- a/database/migrations/create_navigation_trees_table.php.stub
+++ b/database/migrations/create_navigation_trees_table.php.stub
@@ -12,8 +12,8 @@ return new class extends Migration {
             $table->string('handle');
             $table->string('type')->index();
             $table->string('locale')->nullable()->index();
-            $table->json('tree')->nullable();
-            $table->json('settings')->nullable();
+            $table->jsonb('tree')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
 
             $table->unique(['handle', 'type', 'locale']);
diff --git a/database/migrations/create_navigations_table.php.stub b/database/migrations/create_navigations_table.php.stub
index 8ca6b42..d86b1e2 100644
--- a/database/migrations/create_navigations_table.php.stub
+++ b/database/migrations/create_navigations_table.php.stub
@@ -11,7 +11,7 @@ return new class extends Migration {
             $table->id();
             $table->string('handle')->unique();
             $table->string('title');
-            $table->json('settings')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_revisions_table.php.stub b/database/migrations/create_revisions_table.php.stub
index 8dc84d5..4a78741 100644
--- a/database/migrations/create_revisions_table.php.stub
+++ b/database/migrations/create_revisions_table.php.stub
@@ -13,7 +13,7 @@ return new class extends Migration {
             $table->string('action')->index();
             $table->string('user')->nullable();
             $table->string('message')->nullable();
-            $table->json('attributes')->nullable();
+            $table->jsonb('attributes')->nullable();
             $table->timestamps();
 
             $table->unique(['key', 'created_at']);
diff --git a/database/migrations/create_taxonomies_table.php.stub b/database/migrations/create_taxonomies_table.php.stub
index d19218e..810d544 100644
--- a/database/migrations/create_taxonomies_table.php.stub
+++ b/database/migrations/create_taxonomies_table.php.stub
@@ -11,8 +11,8 @@ return new class extends Migration {
             $table->id();
             $table->string('handle')->unique();
             $table->string('title');
-            $table->json('sites')->nullable();
-            $table->json('settings')->nullable();
+            $table->jsonb('sites')->nullable();
+            $table->jsonb('settings')->nullable();
             $table->timestamps();
         });
     }
diff --git a/database/migrations/create_terms_table.php.stub b/database/migrations/create_terms_table.php.stub
index e53afe1..22c8af6 100644
--- a/database/migrations/create_terms_table.php.stub
+++ b/database/migrations/create_terms_table.php.stub
@@ -13,7 +13,7 @@ return new class extends Migration {
             $table->string('slug');
             $table->string('uri')->nullable()->index();
             $table->string('taxonomy')->index();
-            $table->json('data');
+            $table->jsonb('data');
             $table->timestamps();
 
             $table->unique(['slug', 'taxonomy', 'site']);
diff --git a/database/migrations/updates/add_order_to_entries_table.php.stub b/database/migrations/updates/add_order_to_entries_table.php.stub
new file mode 100644
index 0000000..520d076
--- /dev/null
+++ b/database/migrations/updates/add_order_to_entries_table.php.stub
@@ -0,0 +1,21 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use Statamic\Eloquent\Database\BaseMigration as Migration;
+
+return new class extends Migration {
+    public function up()
+    {
+        Schema::table($this->prefix('entries'), function (Blueprint $table) {
+            $table->integer('order')->after('collection')->nullable();
+        });
+    }
+
+    public function down()
+    {
+        Schema::table($this->prefix('entries'), function (Blueprint $table) {
+            $table->dropColumn('order');
+        });
+    }
+};
diff --git a/src/Collections/Collection.php b/src/Collections/Collection.php
index 418f669..c0676d7 100644
--- a/src/Collections/Collection.php
+++ b/src/Collections/Collection.php
@@ -28,6 +28,7 @@ class Collection extends FileEntry
             ->searchIndex($model->settings['search_index'] ?? null)
             ->revisionsEnabled($model->settings['revisions'] ?? false)
             ->defaultPublishState($model->settings['default_status'] ?? true)
+            ->originBehavior($model->settings['origin_behavior'] ?? 'select')
             ->structureContents($model->settings['structure'] ?? null)
             ->sortField($model->settings['sort_field'] ?? null)
             ->sortDirection($model->settings['sort_dir'] ?? null)
@@ -73,6 +74,7 @@ class Collection extends FileEntry
                 'past_date_behavior'   => $source->pastDateBehavior(),
                 'future_date_behavior' => $source->futureDateBehavior(),
                 'preview_targets'      => $source->previewTargets(),
+                'origin_behavior'      => $source->originBehavior(),
             ],
         ]);
     }
diff --git a/src/Collections/CollectionRepository.php b/src/Collections/CollectionRepository.php
index 25cb76d..4cf6f39 100644
--- a/src/Collections/CollectionRepository.php
+++ b/src/Collections/CollectionRepository.php
@@ -78,4 +78,9 @@ class CollectionRepository extends StacheRepository
             CollectionContract::class => Collection::class,
         ];
     }
+
+    public function updateEntryOrder(CollectionContract $collection, $ids = null)
+    {
+        $collection->queryEntries()->get()->each->save();
+    }
 }
diff --git a/src/Commands/ImportCollections.php b/src/Commands/ImportCollections.php
index aeea7d4..bb6f5de 100644
--- a/src/Commands/ImportCollections.php
+++ b/src/Commands/ImportCollections.php
@@ -2,7 +2,9 @@
 
 namespace Statamic\Eloquent\Commands;
 
+use Closure;
 use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Facade;
 use Statamic\Console\RunsInPlease;
 use Statamic\Contracts\Entries\Collection as CollectionContract;
 use Statamic\Contracts\Entries\CollectionRepository as CollectionRepositoryContract;
@@ -40,19 +42,34 @@ class ImportCollections extends Command
      */
     public function handle()
     {
-        $this->useDefaultRepositories();
+        $this->usingDefaultRepositories(function () {
+            $this->importCollections();
+        });
+
+        $this->updateEntryOrder();
 
-        $this->importCollections();
+        $this->newLine();
+        $this->info('Collections imported');
 
         return 0;
     }
 
-    private function useDefaultRepositories()
+    private function usingDefaultRepositories(Closure $callback)
     {
+        $originalRepo = get_class(app()->make(CollectionRepositoryContract::class));
+        $originalTreeRepo = get_class(app()->make(CollectionTreeRepositoryContract::class));
+        $originalCollection = get_class(app()->make(CollectionContract::class));
+
         Statamic::repository(CollectionRepositoryContract::class, CollectionRepository::class);
         Statamic::repository(CollectionTreeRepositoryContract::class, CollectionTreeRepository::class);
-
         app()->bind(CollectionContract::class, StacheCollection::class);
+
+        $callback();
+
+        Statamic::repository(CollectionRepositoryContract::class, $originalRepo);
+        Statamic::repository(CollectionTreeRepositoryContract::class, $originalTreeRepo);
+        app()->bind(CollectionContract::class, $originalCollection);
+        Facade::clearResolvedInstance(CollectionRepositoryContract::class);
     }
 
     private function importCollections()
@@ -74,8 +91,12 @@ class ImportCollections extends Command
                 });
             }
         });
+    }
 
-        $this->newLine();
-        $this->info('Collections imported');
+    private function updateEntryOrder()
+    {
+        $this->withProgressBar(CollectionFacade::all(), function ($collections) {
+            $collections->updateEntryOrder();
+        });
     }
 }
diff --git a/src/Commands/ImportEntries.php b/src/Commands/ImportEntries.php
index c6a5726..88088c7 100644
--- a/src/Commands/ImportEntries.php
+++ b/src/Commands/ImportEntries.php
@@ -56,11 +56,30 @@ class ImportEntries extends Command
     {
         $entries = Entry::all();
 
-        $this->withProgressBar($entries, function ($entry) {
+        $entriesWithOrigin = $entries->filter->hasOrigin();
+        $entriesWithoutOrigin = $entries->filter(function ($entry) {
+            return ! $entry->hasOrigin();
+        });
+
+        if ($entriesWithOrigin->count() > 0) {
+            $this->info('Importing origin entries');
+        }
+
+        $this->withProgressBar($entriesWithoutOrigin, function ($entry) {
             $lastModified = $entry->fileLastModified();
             $entry->toModel()->fill(['created_at' => $lastModified, 'updated_at' => $lastModified])->save();
         });
 
+        if ($entriesWithOrigin->count() > 0) {
+            $this->newLine();
+            $this->info('Importing localized entries');
+
+            $this->withProgressBar($entriesWithOrigin, function ($entry) {
+                $lastModified = $entry->fileLastModified();
+                $entry->toModel()->fill(['created_at' => $lastModified, 'updated_at' => $lastModified])->save();
+            });
+        }
+
         $this->newLine();
         $this->info('Entries imported');
     }
diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php
index e2fff28..5b1fefb 100644
--- a/src/Entries/Entry.php
+++ b/src/Entries/Entry.php
@@ -41,8 +41,7 @@ class Entry extends FileEntry
             $data['blueprint'] = $this->blueprint;
         }
 
-        return $class::findOrNew($this->id())->fill([
-            'id'         => $this->id(),
+        $attributes = [
             'origin_id'  => $this->origin()?->id(),
             'site'       => $this->locale(),
             'slug'       => $this->slug(),
@@ -53,7 +52,14 @@ class Entry extends FileEntry
             'published'  => $this->published(),
             'status'     => $this->status(),
             'updated_at' => $this->lastModified(),
-        ]);
+            'order'      => $this->order(),
+        ];
+
+        if ($id = $this->id()) {
+            $attributes['id'] = $id;
+        }
+
+        return $class::findOrNew($id)->fill($attributes);
     }
 
     public function model($model = null)
@@ -76,6 +82,11 @@ class Entry extends FileEntry
         return $this->model?->updated_at ?? Carbon::now();
     }
 
+    public function lastModified()
+    {
+        return $this->fileLastModified();
+    }
+
     public function origin($origin = null)
     {
         if (func_num_args() > 0) {
diff --git a/src/Entries/EntryQueryBuilder.php b/src/Entries/EntryQueryBuilder.php
index 8e94f2b..748ba89 100644
--- a/src/Entries/EntryQueryBuilder.php
+++ b/src/Entries/EntryQueryBuilder.php
@@ -15,13 +15,14 @@ class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
 
     const COLUMNS = [
         'id', 'site', 'origin_id', 'published', 'status', 'slug', 'uri',
-        'date', 'collection', 'created_at', 'updated_at',
+        'date', 'collection', 'created_at', 'updated_at', 'order',
     ];
 
     protected function transform($items, $columns = [])
     {
-        $items = EntryCollection::make($items)->map(function ($model) {
-            return app('statamic.eloquent.entries.entry')::fromModel($model);
+        $items = EntryCollection::make($items)->map(function ($model) use ($columns) {
+            return app('statamic.eloquent.entries.entry')::fromModel($model)
+                ->selectedQueryColumns($columns);
         });
 
         return Entry::applySubstitutions($items);
@@ -33,6 +34,9 @@ class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
             return $column;
         }
 
+        $table = Str::contains($column, '.') ? Str::before($column, '.') : '';
+        $column = Str::after($column, '.');
+
         if ($column == 'origin') {
             $column = 'origin_id';
         }
@@ -43,7 +47,7 @@ class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
             }
         }
 
-        return $column;
+        return ($table ? $table.'.' : '').$column;
     }
 
     public function find($id, $columns = ['*'])
@@ -67,7 +71,7 @@ class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
     {
         $this->addTaxonomyWheres();
 
-        return parent::paginate($perPage, $columns, $pageName = 'page', $page = null);
+        return parent::paginate($perPage, $columns, $pageName, $page);
     }
 
     public function count()
@@ -76,4 +80,9 @@ class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
 
         return parent::count();
     }
+
+    public function with($relations, $callback = null)
+    {
+        return $this;
+    }
 }
diff --git a/src/Entries/EntryRepository.php b/src/Entries/EntryRepository.php
index 37fb58d..34af791 100644
--- a/src/Entries/EntryRepository.php
+++ b/src/Entries/EntryRepository.php
@@ -55,6 +55,9 @@ class EntryRepository extends StacheRepository
         $model->save();
 
         $entry->model($model->fresh());
+
+        Blink::put("eloquent-entry-{$entry->id()}", $entry);
+        Blink::put("eloquent-entry-{$entry->uri()}", $entry);
     }
 
     public function delete($entry)
diff --git a/src/Forms/Submission.php b/src/Forms/Submission.php
index 9fa2672..0bd271c 100644
--- a/src/Forms/Submission.php
+++ b/src/Forms/Submission.php
@@ -2,6 +2,7 @@
 
 namespace Statamic\Eloquent\Forms;
 
+use Illuminate\Support\Carbon;
 use Statamic\Eloquent\Forms\SubmissionModel as Model;
 use Statamic\Events\SubmissionDeleted;
 use Statamic\Events\SubmissionSaved;
@@ -25,13 +26,16 @@ class Submission extends FileEntry
     public function toModel()
     {
         $class = app('statamic.eloquent.forms.submission_model');
-        $timestamp = (new $class())->fromDateTime($this->date());
+        $timestamp = (new $class)->fromDateTime($this->date());
 
-        return $class::firstOrNew([
-            'form_id'    => $this->form->model()->id,
-            'created_at' => $timestamp,
-        ])->fill([
+        $model = $class::findOrNew($this->id());
+
+        return (! empty($model->id)) ? $model->fill([
             'data' => $this->data,
+        ]) : $model->fill([
+            'data' => $this->data,
+            'form_id' => $this->form->model()->id,
+            'created_at' => $timestamp,
         ]);
     }
 
@@ -52,7 +56,7 @@ class Submission extends FileEntry
             $this->date = $date;
         }
 
-        return $this->date;
+        return $this->date ?? ($this->date = Carbon::now());
     }
 
     public function save()
diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php
index 60712c8..d7b05ee 100644
--- a/src/ServiceProvider.php
+++ b/src/ServiceProvider.php
@@ -37,6 +37,10 @@ class ServiceProvider extends AddonServiceProvider
 
     protected $migrationCount = 0;
 
+    protected $updateScripts = [
+        \Statamic\Eloquent\Updates\AddOrderToEntriesTable::class,
+    ];
+
     public function boot()
     {
         parent::boot();
diff --git a/src/Taxonomies/Term.php b/src/Taxonomies/Term.php
index bdb35e2..190673f 100644
--- a/src/Taxonomies/Term.php
+++ b/src/Taxonomies/Term.php
@@ -54,7 +54,7 @@ class Term extends FileEntry
     {
         $class = app('statamic.eloquent.terms.model');
 
-        $data = $source->data();
+        $data = $source->fileData();
 
         if (! isset($data['template'])) {
             unset($data['template']);
diff --git a/src/Taxonomies/TermQueryBuilder.php b/src/Taxonomies/TermQueryBuilder.php
index 32a563b..2afbd94 100644
--- a/src/Taxonomies/TermQueryBuilder.php
+++ b/src/Taxonomies/TermQueryBuilder.php
@@ -2,6 +2,7 @@
 
 namespace Statamic\Eloquent\Taxonomies;
 
+use Illuminate\Support\Arr;
 use Illuminate\Support\Str;
 use Statamic\Contracts\Taxonomies\Term as TermContract;
 use Statamic\Facades\Collection;
@@ -197,7 +198,7 @@ class TermQueryBuilder extends EloquentQueryBuilder
     {
         $this->applyCollectionAndTaxonomyWheres();
 
-        return parent::paginate($perPage = null, $columns = [], $pageName = 'page', $page = null);
+        return parent::paginate($perPage, $columns, $pageName, $page);
     }
 
     private function applyCollectionAndTaxonomyWheres()
@@ -217,7 +218,7 @@ class TermQueryBuilder extends EloquentQueryBuilder
                         $slugs = [];
                         foreach ($entry->collection()->taxonomies()->map->handle() as $taxonomy) {
                             if (in_array($taxonomy, $taxonomies)) {
-                                foreach ($entry->get($taxonomy, []) as $term) {
+                                foreach (Arr::wrap($entry->get($taxonomy, [])) as $term) {
                                     $slugs[] = $taxonomy.'::'.$term;
                                 }
                             }
@@ -254,4 +255,9 @@ class TermQueryBuilder extends EloquentQueryBuilder
             }
         }
     }
+
+    public function with($relations, $callback = null)
+    {
+        return $this;
+    }
 }
diff --git a/src/Taxonomies/TermRepository.php b/src/Taxonomies/TermRepository.php
index b43ab4e..3ed6248 100644
--- a/src/Taxonomies/TermRepository.php
+++ b/src/Taxonomies/TermRepository.php
@@ -85,8 +85,6 @@ class TermRepository extends StacheRepository
         $model = $entry->toModel();
         $model->save();
 
-        //var_dump($entry->data());
-
         $entry->model($model->fresh());
     }
 
diff --git a/src/Updates/AddOrderToEntriesTable.php b/src/Updates/AddOrderToEntriesTable.php
new file mode 100644
index 0000000..ac95478
--- /dev/null
+++ b/src/Updates/AddOrderToEntriesTable.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Statamic\Eloquent\Updates;
+
+use Illuminate\Support\Facades\Schema;
+use Statamic\UpdateScripts\UpdateScript;
+
+class AddOrderToEntriesTable extends UpdateScript
+{
+    public function shouldUpdate($newVersion, $oldVersion)
+    {
+        return $this->isUpdatingTo('1.0.3')
+            && ! Schema::hasColumn(config('statamic.eloquent-driver.table_prefix', '').'entries', 'order');
+    }
+
+    public function update()
+    {
+        $source = __DIR__.'/../../database/migrations/updates/add_order_to_entries_table.php.stub';
+        $dest = database_path('migrations/'.date('Y_m_d_His').'_add_order_to_entries_table.php');
+
+        $this->files->copy($source, $dest);
+
+        $this->console()->info('Migration created');
+        $this->console()->comment('Remember to run `php artisan migrate` to apply it to your database.');
+    }
+}


Test patch:
diff --git a/tests/Data/Entries/EntryQueryBuilderTest.php b/tests/Data/Entries/EntryQueryBuilderTest.php
index b47c2f3..1116fa5 100644
--- a/tests/Data/Entries/EntryQueryBuilderTest.php
+++ b/tests/Data/Entries/EntryQueryBuilderTest.php
@@ -688,4 +688,42 @@ class EntryQueryBuilderTest extends TestCase
         $this->assertCount(2, $entries);
         $this->assertEquals(['Post 2', 'Post 3'], $entries->map->title->all());
     }
+
+    /** @test */
+    public function entries_can_be_retrieved_on_join_table_conditions()
+    {
+        Collection::make('posts')->save();
+        EntryFactory::id('1')->slug('post-1')->collection('posts')->data(['title' => 'Post 1', 'author' => 'John Doe', 'location' => 4])->create();
+        EntryFactory::id('2')->slug('post-2')->collection('posts')->data(['title' => 'Post 2', 'author' => 'John Doe'])->create();
+        EntryFactory::id('3')->slug('post-3')->collection('posts')->data(['title' => 'Post 3', 'author' => 'John Doe', 'location' => 4])->create();
+        Collection::make('locations')->save();
+
+        $locations = [
+            4 => ['slug' => 'shaldon', 'title' => 'Shaldon'],
+            5 => ['slug' => 'cambridge', 'title' => 'Cambridge'],
+            6 => ['slug' => 'london', 'title' => 'London'],
+        ];
+
+        foreach (range(4, 6) as $index) {
+            EntryFactory::id($index)->slug($locations[$index]['slug'])->collection('locations')
+            ->data(['title' => $locations[$index]['title']])->create();
+        }
+
+        $query = Entry::query()
+            ->join('entries as e', fn ($join) => $join
+                ->whereColumn('e.id', 'entries.id')
+                ->where('e.collection', 'posts')
+            )->leftJoin('entries as locations', function ($join) {
+                $join
+                    ->where('locations.collection', 'locations')
+                    ->on('locations.id', 'e.data->location');
+            })
+            ->where('e.data->title', 'like', '%post%')
+            ->where('locations.slug', 'shaldon');
+
+        $entries = $query->get();
+
+        // successfully retrieved 2 results
+        $this->assertCount(2, $entries);
+    }
 }
diff --git a/tests/Entries/EntryTest.php b/tests/Entries/EntryTest.php
index 8285cdb..7baad71 100644
--- a/tests/Entries/EntryTest.php
+++ b/tests/Entries/EntryTest.php
@@ -44,7 +44,7 @@ class EntryTest extends TestCase
             'published'  => false,
             'status'     => 'draft',
             'origin_id'  => null,
-            'id'         => null,
+            'order'      => null,
         ]);
 
         $collection = Collection::make('blog')->title('blog')->routes([
diff --git a/tests/Forms/FormSubmissionTest.php b/tests/Forms/FormSubmissionTest.php
new file mode 100644
index 0000000..5131dab
--- /dev/null
+++ b/tests/Forms/FormSubmissionTest.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Tests\Forms;
+
+use Carbon\Carbon;
+use Statamic\Eloquent\Forms\FormModel;
+use Statamic\Eloquent\Forms\SubmissionModel;
+use Tests\TestCase;
+
+class FormSubmissionTest extends TestCase
+{
+    /** @test */
+    public function it_should_have_timestamps()
+    {
+        $form = FormModel::create([
+            'handle' => 'test',
+            'title' => 'Test',
+        ]);
+
+        $submission = SubmissionModel::create([
+            'form_id' => $form->id,
+            'data' => [
+                'name' => 'John Doe',
+            ],
+        ]);
+
+        $this->assertInstanceOf(Carbon::class, $submission->created_at);
+        $this->assertInstanceOf(Carbon::class, $submission->updated_at);
+    }
+
+    /** @test */
+    public function it_should_save_to_the_database()
+    {
+        $form = FormModel::create([
+            'handle' => 'test',
+            'title' => 'Test',
+        ]);
+
+        $submission = SubmissionModel::create([
+            'form_id' => $form->id,
+            'data' => [
+                'name' => 'John Doe',
+            ],
+        ]);
+
+        $this->assertDatabaseHas('form_submissions', [
+            'id' => $submission->id,
+            'form_id' => $form->id,
+            'data' => json_encode([
+                'name' => 'John Doe',
+            ]),
+        ]);
+    }
+
+    /** @test */
+    public function it_should_not_overwrite_submissions()
+    {
+        $form = FormModel::create([
+            'handle' => 'test',
+            'title' => 'Test',
+        ]);
+
+        $submission = SubmissionModel::create([
+            'form_id' => $form->id,
+            'data' => [
+                'name' => 'John Doe',
+            ],
+        ]);
+
+        $submission = SubmissionModel::create([
+            'form_id' => $form->id,
+            'data' => [
+                'name' => 'Billy Doe',
+            ],
+        ]);
+
+        $this->assertCount(2, $form->submissions()->get());
+    }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 4162679..84bcd13 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -37,7 +37,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
         $uses = array_flip(class_uses_recursive(static::class));
 
         if ($this->shouldFakeVersion) {
-            \Facades\Statamic\Version::shouldReceive('get')->andReturn('3.0.0-testing');
+            \Facades\Statamic\Version::shouldReceive('get')->zeroOrMoreTimes()->andReturn('3.0.0-testing');
             $this->addToAssertionCount(-1); // Dont want to assert this
         }