私の問題を単純化するために、私は私のライブラリ内の借用、カウント、検索、およびブックを追加するためのすべての機能を実装するライブラリシステムのプロジェクトを持っているとしましょう。私のモデルで多対多の関係テーブルによる検索を改善するには?
このプロジェクトでは、person (id, name, etc)
,loan (id, id_person, dates, etc)
、もちろんbook (id, title, etc)
の3つのメインテーブルを作成しました。
人は一度に複数の本を借りることができるので、多対多関係をリンクするために別のテーブルも必要でした。 rel_loan_book (id, id_book, id_loan)
。
私のブックビューでは、本のすべての情報とその本が借用可能かどうか(現時点では使用されていないかどうか)を示す欄を持つGridview
があります。ここで
は、私は現時点ではやっているものです:
ビュー:
[
'attribute' => 'isAvaliable',
'value' => function($model) {
return $model->currentLoan ? 'No' :'Yes';
},
'filter' => Html::activeDropDownList($searchModel, 'isAvaliable', ['1' => 'Yes', '0' => 'No'],
['class'=>'form-control','prompt' => '']
)
],
モデル帳:ローンテーブルの
public function getCurrentLoan()
{
return $this->hasOne(Loan::className(), ['id' => 'id_loan'])
->viaTable(RelLoanBook::tableName(), ['id_book' => 'id'])
->onCondition(['loan.status' => 'A']);
}
ステータス'A'
が、それはまだだ意味しますアクティブ(本は戻ってこなかった)。
私の問題は、利用可能な書籍または利用できない書籍を検索しようとしたときです...現時点では、私は借用した書籍が何であるかを確認してから、これを削除(またはフィルタリング)するだけです私の検索では、IDS:
BookSearch:
public $isAvaliable;
...
public function rules()
{
return [
[['isAvaliable'], 'safe'],
];
}
...
public function search($params)
{
...
if ($this->isAvaliable !== '') {
$subQuery = Book::find()->select('book.id');
$subQuery->joinWith(['currentLoan'])
->andWhere(['is not' , 'loan.id', null])
->all();
if ($this->isAvaliable === '1') {
$query->andWhere(['not in', 'book.id', $subQuery]);
} elseif ($this->isAvaliable === '0') {
$query->andWhere(['in', 'book.id', $subQuery]);
}
}
...
}
私は、これはそのための最善のアプローチであるとは思いません。しかし、私は、サブクエリなしでその検索を行うSQLクエリで考えることはできません。
SELECT * FROM book
LEFT JOIN rel_loan_book ON rel_loan_book.book_id = book.id
LEFT JOIN loan ON loan.id = rel_loan_book.loan.id
WHERE (/* my filters */)
AND (/* some restriction that check if the book does OR does not have a loan with status === 'A' */)
まず第一に、後者の応答に答えると、申し訳ありませんありがとうございました。だから、私は私の質問で確立したように、私は**多対多関係を持っています。 1つのローンに複数のブックを含めることができます。それに加えて、アプローチは良く見えますが、それは私のgridview内の各書籍について、そのチェックを行うSQLクエリを生成することを意味します。私の元のクエリは、単一の検索でそれを作ったが、私はサブクエリなしでそれを行うために探していた。現時点ではすでに進んでいますが、新しい解決策が必要な場合や、見つけたらこの質問を公開します。 – Clyff
あなたが拾い集めた本のうちの1つを完成させ、他のものを手に入れながらそれを返す(他人を家に残す)と、あなたのスキーマは十分ではありません。ブックテーブルにisAvailableカラムを追加して、ブックをピックアップ/戻したときの値を調整することができます。それ以外の場合は、サブクエリが必要です。 – ttdijkstra
私はあなたの意見を見ていますが、現在のシナリオはこのようには見えません。借りた物の一部を返すことはできません。申し訳ありませんが、私は私の質問で言ったように、自分自身を説明するためにライブラリの例を使用しました。実際の図書館プロジェクトでは、あなたのアプローチは正しいです。 – Clyff