はい、ACL はやり過ぎです
ACL は非常に強力で柔軟なシステムですが、無料で提供されるわけではなく、複雑さが伴います。きめ細かいアクセス許可が絶対に必要なユースケースがない限り (説明した 2 つのルールはこれに当てはまりません)、ACL を使用しないでください。
彼が追加したユーザーを書籍に制限する
このルールは簡単に実装できます。たとえば、関連する検索呼び出しに追加します。
$results = $BookModelInstance->find('all', array(
'conditions' => array(
'created_by' => AuthComponent::user('id')
)
));
ユーザーが購入した書籍に限定する
このルールも簡単に実装できますが、少し複雑になります。
$BookModelInstance->bindModel(array(
'hasOne' => array( // Yes, hasOne not hasMany
'MyPurchase' => array(
'className' => 'Purchase',
'foriegnKey' => 'user_id'
)
)
));
$results = $BookModelInstance->find('all', array(
'recursive' => 0, // to join hasOne+belongsTo associations into the query
'conditions' => array(
'MyPurchase.user_id' = AuthComponent::user('id'),
)
));
bindModel 呼び出しは . と同等のものを実現しSELECT .. FROM books LEFT JOIN book_users
ます。したがって、find 呼び出しの条件により、ユーザーが本を購入したという記録がある本に結果が制限されます。
両方を一緒に置く
これらの両方のルールを自動的に適用する単純な実装は次のようになります。
model Book extends AppModel {
public $actsAs = array('Containable');
public $restrictToUser = true;
public function beforeSave($options = array()) {
if (!$this->id) {
// Store who created this book
$this->data[$this->alias]['created_by'] = AuthComponent::user('id');
}
return true;
}
public function beforeFind($queryData) {
if (!$this->restrictToUser) {
// we don't want to apply user-level restrictions
return true;
}
$userId = AuthComponent::user('id');
if (!$userId) {
// we want to restrict to the current user - there isn't one.
return false;
}
// define the association to the purchase table
$this->bindModel(array(
'hasOne' => array(
'MyPurchase' => array(
'className' => 'Purchase',
'foriegnKey' => 'user_id'
)
)
));
//ensure the purchase table is included in the current query
$queryData['contain']['MyPurchase'] = array();
// restrict to rows created by the current user, OR purchased by the current user
$queryData['conditions']['OR'] = array(
$this->alias '.created_by' => $userId,
'MyPurchase.user_id' => $userId
);
return $queryData;
}
}
これにはフィールドcreated_by
(または同等のもの) が books テーブルにある必要があり、containable を使用してpurchases
テーブル (または同等のもの) が関連するすべてのクエリに含まれるようにします。