Cake 2.x:如何为非Inflector约定的控制器关联模型(免重复loadModel)
Great question! I’ve dealt with this exact frustration in CakePHP 2.x before—having to call loadModel() in every controller method is such a drag. Here are two clean, maintainable ways to fix this without repeating code:
1. Use the Controller's $uses Property (Recommended)
This is the most "CakePHP-native" approach. The $uses property lets you explicitly define which models your controller should load automatically, bypassing the default Inflector-based naming convention.
Just add it to the top of your controller class, like this:
class UnconventionalController extends AppController { // Explicitly define the models this controller needs public $uses = array('CustomModel', 'AnotherNonStandardModel'); public function index() { // No need for loadModel() here! $data = $this->CustomModel->find('all'); $this->set(compact('data')); } public function view($id) { // Works here too $record = $this->AnotherNonStandardModel->findById($id); $this->set(compact('record')); } }
- If you only need one model, you can pass a string instead of an array:
public $uses = 'SingleCustomModel'; - This method loads the models when the controller is initialized, so they’re available in every method automatically.
2. Load Models in beforeFilter() (For Dynamic Scenarios)
If you need more flexibility—like loading different models based on certain conditions, or if you prefer not to use $uses—you can call loadModel() once in the controller’s beforeFilter() method. This runs before every action in the controller, so the model will be available everywhere.
Example:
class SpecialOrdersController extends AppController { public function beforeFilter() { parent::beforeFilter(); // Always call the parent method! // Load your non-standard model once here $this->loadModel('SpecialOrder'); } public function create() { // Model is already loaded if ($this->request->is('post')) { $this->SpecialOrder->create(); if ($this->SpecialOrder->save($this->request->data)) { $this->Session->setFlash('Order saved!'); $this->redirect(array('action' => 'index')); } } } public function edit($id) { // No loadModel() needed here either $order = $this->SpecialOrder->findById($id); $this->set(compact('order')); } }
Which One to Choose?
- Use
$usesif you have fixed model associations for the controller—it’s cleaner and aligns with CakePHP’s design patterns. - Use
beforeFilter()if you need dynamic model loading (e.g., loading different models for admin vs. front-end actions) or if you’re working with a legacy codebase where$usesisn’t already in use.
内容的提问来源于stack exchange,提问作者Ritesh

