2017-06-15 19 views
0

モデルに追加属性を使用した特別な理由で、whereクエリをカスタム属性(たとえば、カテゴリ)にしたいときは、私は直面します「カテゴリ」という名前の列が見つかりませんでした。Laravelでクエリを実行する別のテーブルに結果が出る5.4

この問題を解決するために、私はクエリテーブルの結果をテンポラリテーブルに入れればいいと思います!

誰かにそれについてのアイデアはありますか?それが私にとって便利な場合、結果を一時テーブルにどのように転送できますか?

答えて

0

生の文を使用してテンポラリ・テーブルを作成できます。この投稿は、かなりそれ以上の深さに行く:

https://laracasts.com/discuss/channels/laravel/how-to-implement-temporary-table

+0

しかし、私はクエリテーブルを一時テーブルに入れたいですか? –

+0

ええ、私はなぜ、メモリ内のSQLite接続と同じように、データが接続終了時にすべてそこにあるのかわかりません。 – btl

1

あなたは、そのフィールドは明らかにデータベースに存在しないため、モデルアクセサのダイナミックなフィールドを使用してデータベースクエリを制限することはできません。

ただし、コレクションオブジェクトはかなり強力なフィルタリング機能を備えているため、データベースの照会後に動的フィールドを使用してコレクション結果をフィルタリングできます。これは、データベースから検索する前に結果をフィルタリングするのと同じようにパフォーマンスは良くありませんが、パフォーマンスがそれほど重要ではない場合や、コードの清浄度/保守コストがパフォーマンスコストを上回る場合があります。一例として、

、以下のモデル与えられた:

$childrenBooks = Book::where('category', 'child')->get(); // error: no category field 

ただし、次のように:categoryフィールドは、実際にテーブルに存在しないため、次のクエリは動作しません

class Book extends Model 
{ 
    public function getCategoryAttribute() 
    { 
     if ($this->targetAge < 13) { 
      return 'child'; 
     } 

     if ($this->targetAge < 18) { 
      return 'teen'; 
     } 

     return 'adult'; 
    } 
} 

をデータベースから返されたモデルのコレクションでwhere()を呼び出しているため、モデルは動的フィールドにアクセスできます:

$childrenBooks = Book::get()->where('category', 'child'); 

この場合の問題は、動作している間にデータベースからすべての書籍を取得し、それぞれのモデルインスタンスを作成し、そのフルコレクションをフィルタリングすることです。ただし、アクセッサメソッドでロジックを複製する必要はありません。これは、あなたが賛否両論を計量し、あなたの状況でこれが受け入れられるかどうかを判断する必要があるところです。

中間オプションは、(それがクエリのために複製することができる場合)あなたのアクセサロジックは一つだけの場所に複製されるように、モデルのスコープメソッドを作成するには、次のようになります。

class Book extends Model 
{ 
    public function getCategoryAttribute() 
    { 
     if ($this->targetAge < 13) { 
      return 'child'; 
     } 

     if ($this->targetAge < 18) { 
      return 'teen'; 
     } 

     return 'adult'; 
    } 

    public function scopeCategory($query, $category) 
    { 
     if ($category == 'child') { 
      return $query->where('target_age', '<', 13); 
     } 

     if ($category == 'teen') { 
      return $query->where(function ($query) { 
       return $query 
        ->where('target_age', '>=', 13) 
        ->where('target_age', '<', 18); 
      }); 
     } 

     return $query->where('target_age', '>=', 18); 
    } 
} 

次に、あなたがこれを使用することができますそのようなクエリのスコープ:

$childrenBooks = Book::category('child')->get(); 

ここでの利点は、ロジックは、実際のクエリに適用されるということですので、彼らは、データベースから返される前にレコードが制限されています。主な問題は、今度はあなたの「カテゴリ」ロジックが、アクセッサに一度、スコープに一度複製されることです。さらに、これは、アクセサロジックをデータベースクエリで処理できるものに変換できる場合にのみ機能します。

+0

多くの学習のヒントが含まれているので、私はあなたの答えを投票しましたが、私の問題はこれで解決されませんでした!ありがとう。 –

+0

@BehnamAzimi何を試しましたか?何がうまくいかなかったのですか? – patricus

+0

私はすべてのチャンネルのカテゴリを検索し、私が必要とするカテゴリを持つチャンネルを選択したいと思っていました。あなたの方法で私は私のカテゴリでwhere句を行うことができませんでした。私は "カテゴリの列はテーブルに存在しません"というエラーに直面しました。だから私は多くのことを試して、最後に私の問題を解決しました!私はすぐに[この質問](https://stackoverflow.com/questions/44582775/where-query-after-wherehas-not-work-as-it-should-in-laravel-5-4)に回答します。/44582967?noredirect = 1#comment76158424_44582967)。 –

関連する問題