zink's avatar
Level 11

Rest Request as Eloquent Model

I am wondering if it is somehow possible to create a rest query in a temporary MySQL table that I cache e.g. for a few hours so that it can be accessed as an eloquent model. Currently I use Sushi which is great but I would like to use all relation functions as for example hasManyTrough or whereHas.

0 likes
3 replies
LaryAI's avatar
Level 58

Creating a temporary MySQL table to cache REST query results and then accessing it as an Eloquent model is an interesting approach. While Sushi provides a way to use Eloquent with arrays, it doesn't support relationships out of the box. However, you can achieve your goal by creating a custom solution that involves the following steps:

  1. Fetch the data from the REST API.
  2. Create a temporary MySQL table and insert the fetched data into it.
  3. Define an Eloquent model that interacts with the temporary table.
  4. Define relationships in the Eloquent model as you would with a regular model.
  5. Cache the table creation and data insertion process to avoid unnecessary operations.

Here's a simplified example of how you might implement this:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;

class RestData extends Model
{
    protected $table = 'rest_data_temporary';

    // Define relationships here
    public function relatedModels()
    {
        return $this->hasMany(RelatedModel::class);
    }
}

// Fetch data from the REST API
$restData = fetchDataFromApi(); // Implement this function to fetch data from your API

// Generate a unique table name to avoid conflicts
$temporaryTableName = 'rest_data_temporary_' . time();

// Create a temporary table
Schema::create($temporaryTableName, function (Blueprint $table) {
    $table->increments('id');
    // Define other columns based on the structure of your REST data
});

// Insert data into the temporary table
foreach ($restData as $data) {
    DB::table($temporaryTableName)->insert([
        // Map your REST data to the corresponding columns
    ]);
}

// Set the table name for the Eloquent model dynamically
RestData::resolveConnection()->setTable($temporaryTableName);

// Use the Eloquent model as usual
$restModelInstance = RestData::whereHas('relatedModels', function ($query) {
    // Your query constraints here
})->get();

// Remember to clean up the temporary table after use or via a scheduled job
Schema::dropIfExists($temporaryTableName);

Remember to replace fetchDataFromApi, RelatedModel, and the column definitions with your actual API fetching function, related Eloquent model, and data structure.

Also, consider the following:

  • You may want to add indexing to your temporary table for performance reasons.
  • Ensure that the temporary table is removed after it's no longer needed to avoid cluttering your database.
  • You can use Laravel's caching system to cache the existence of the table and its data to avoid recreating it unnecessarily.

This is a custom solution and might require further optimization based on the specific use case and data volume.

Snapey's avatar

You can use all relation types with Sushi ?

zink's avatar
Level 11

Actually I have an Eloquent->Sushi->Sushi->Eloquent relation which I want to simplify without any success. With hasManyTrough or whereHas I have problems because the sql query is on a different database which makes sense since Sushi use SQLite b ackend.

Please or to participate in this conversation.