簡體   English   中英

請如何將此原始 sql 查詢轉換為 laravel eloquent 或查詢生成器?

[英]Please How to convert this raw sql query to laravel eloquent or query builder?

你好 Laravel 開發者,美好的一天。 請問如何將原始 sql 查詢轉換為 laravel 查詢構建器或雄辯的 ORM。

我有以下型號:

關系

模型服務器

  public function users()
    {
        return $this->belongsToMany(User::class,'server_users')->withPivot('spam','inbox');;
    }

    public function users_cancellation()
    {
        return $this->belongsToMany(User::class,'server_user_cancellations')->withPivot('spam','inbox');;
    }

模型用戶

   public function servers(): BelongsToMany
    {
        return $this->belongsToMany(Server::class, 'server_users');
    }

    public function servers_cancellation(): BelongsToMany
    {
        return $this->belongsToMany(Server::class, 'server_user_cancellations');
    }

用戶

   $table->id();
            $table->string('full_name');
            $table->string('username')->unique();
            $table->string('password');
            $table->string('type');
            $table->boolean('is_active')->default(true);
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();

服務器

    Schema::create('servers', function (Blueprint $table) {
            $table->id();
            $table->string('name')->default('SM');
            $table->ipAddress('ip')->unique();
            $table->string('username')->default('root');
            $table->boolean('is_active')->default(true);
            $table->softDeletes();
            $table->timestamps();
        });

Server_user_cancellations

   Schema::create('server_user_cancellations', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(Server::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate();
            $table->foreignIdFor(User::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete();
            $table->boolean('spam')->nullable();
            $table->boolean('inbox')->nullable();
            $table->timestamps();
        });

服務器_用戶

  Schema::create('server_users', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(Server::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate();
            $table->foreignIdFor(User::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete();
            $table->boolean('spam')->nullable();
            $table->boolean('inbox')->nullable();
            $table->timestamps();
        });

我想將此原始 sql 查詢轉換為 laravel eloquent 或查詢生成器?

if ($request->wantsJson()) {
  $servers = DB::select('
  SELECT 
    s.name,
    s.id,
    s.ip,
    (SELECT count(id) 
      FROM server_user_cancellations 
      where server_id = s.id and user_id=?
    ) as exist
  FROM servers s
  WHERE s.id IN
    (SELECT  distinct server_id from server_users  where user_id=?)
    AND s.is_active=true
    AND s.is_installed=true
    AND s."deleted_at" is null', 
  [auth()->id(), auth()->id()]
);

從查詢中我假設Server可以屬於許多User並且User可以有很多Server ,並且兩者都有很多ServerUserCancellation ,因此您需要具有取消存在標志的當前用戶的服務器

首先定義適合您的數據庫模式的關系

// Server model
public function cancellations(){
  return $this->hasMany(ServerUserCancellation::class);
}

public function users(){
  return $this->belongsToMany(User::class);
}

// User model
public function servers(){
  return $this->belongsToMany(Server::class);
}

現在您可以根據users關系計算取消和過濾具有當前用戶的服務器

$baseFilters = [
  'is_active' => true,
  'is_installed' => true,  
];
$result = Server::where($basicFilters)
  ->whereNull('deleted_at')
  ->whereHas('users', function($query){
      $query->where('user_id', auth()->id());
    })
  ->withCount(['cancellations as exists' => function($query){
      $query->where('user_id', auth()->id();
    }])
  ->select(['id', 'ip', 'name'])
  ->get();

//result strucure will be looking like this
array(
  [
    'id': 1,
    'ip': '127.0.0.1',
    'name': 'server 1 name',
    'exists': 0  
  ], 
  ...
) 

為了使控制器更干凈,有軟刪除機制來跳過每個Server查詢和范圍whereNull('deleted_at')以使代碼易於閱讀

// Server model
class Server extends Model {
  use SoftDeletes;

  public function scopeActive($query){
    return $query->where('is_active', true);
  }

  public function scopeInstalled($query){
    return $query->where('is_installed', true);
  }

  // ... other model code
}

代碼看起來像這樣

$result = Server::active()
  ->installed()
  ->whereHas('users', function($query){
      $query->where('user_id', auth()->id());
    })
  ->withCount(['cancellations as exists' => function($query){
      $query->where('user_id', auth()->id();
    }])
  ->select(['id', 'ip', 'name'])
  ->get();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM