CakePHP метод поиска с помощью JOIN

Здравствуй,

Мне нужно выполнить следующий запрос с помощью метода find CakePHP:

 SELECT * FROM `messages` INNER JOIN users ON messages.from = users.id WHERE messages.to = 4 ORDER BY messages.datetime DESC 

В основном я:

  • таблица messages с моделью Message
  • таблица users с моделью User

и хотите получить информацию из обеих таблиц в одном запросе. Поле users.id полем messages.from , так что это соединение.

Я делаю это в своем MessagesController поэтому это должно быть что-то вроде:

 $this->Message->find(); 

благодаря

Вы можете сделать это двумя основными способами. Один из них – стандартный способ CakePHP, а другой – пользовательское соединение.

Стоит отметить, что этот совет предназначен для CakePHP 2.x, а не 3.x.

Путь CakePHP

Вы должны создать связь с моделью пользователя и моделью сообщений и использовать сдерживаемое поведение:

 class User extends AppModel { public $actsAs = array('Containable'); public $hasMany = array('Message'); } class Message extends AppModel { public $actsAs = array('Containable'); public $belongsTo = array('User'); } 

Вам нужно изменить столбец messages.from чтобы быть messages.user_id чтобы торт мог автоматически ассоциировать записи для вас.

Затем вы можете сделать это из контроллера сообщений:

 $this->Message->find('all', array( 'contain' => array('User') 'conditions' => array( 'Message.to' => 4 ), 'order' => 'Message.datetime DESC' )); 

Другой способ CakePHP

Я рекомендую использовать первый метод, потому что это сэкономит вам много времени и работы. Первый метод также создает основу для установления отношений, которые могут использоваться для любого количества других находок и условий, кроме того, что вам нужно сейчас. Однако cakePHP поддерживает синтаксис для определения ваших собственных соединений. Это будет сделано с помощью MessagesController :

 $this->Message->find('all', array( 'joins' => array( array( 'table' => 'users', 'alias' => 'UserJoin', 'type' => 'INNER', 'conditions' => array( 'UserJoin.id = Message.from' ) ) ), 'conditions' => array( 'Message.to' => 4 ), 'fields' => array('UserJoin.*', 'Message.*'), 'order' => 'Message.datetime DESC' )); 

Обратите внимание: я оставил messages.from с именами полей. Так же, как и текущая таблица в этом примере.

Используя два отношения к одной и той же модели

Вот как вы можете сделать первый пример, используя два отношения к одной и той же модели:

 class User extends AppModel { public $actsAs = array('Containable'); public $hasMany = array( 'MessagesSent' => array( 'className' => 'Message', 'foreignKey' => 'from' ) ); public $belongsTo = array( 'MessagesReceived' => array( 'className' => 'Message', 'foreignKey' => 'to' ) ); } class Message extends AppModel { public $actsAs = array('Containable'); public $belongsTo = array( 'UserFrom' => array( 'className' => 'User', 'foreignKey' => 'from' ) ); public $hasMany = array( 'UserTo' => array( 'className' => 'User', 'foreignKey' => 'to' ) ); } 

Теперь вы можете сделать свой вызов:

 $this->Message->find('all', array( 'contain' => array('UserFrom') 'conditions' => array( 'Message.to' => 4 ), 'order' => 'Message.datetime DESC' )); 

Пример Отро, пользовательское разбиение на данные для JOIN

КОД в контроллере CakePHP 2.6 в порядке:

 $this->SenasaPedidosFacturadosSds->recursive = -1; // Filtro $where = array( 'joins' => array( array( 'table' => 'usuarios', 'alias' => 'Usuarios', 'type' => 'INNER', 'conditions' => array( 'Usuarios.usuario_id = SenasaPedidosFacturadosSds.usuarios_id' ) ), array( 'table' => 'senasa_pedidos', 'alias' => 'SenasaPedidos', 'type' => 'INNER', 'conditions' => array( 'SenasaPedidos.id = SenasaPedidosFacturadosSds.senasa_pedidos_id' ) ), array( 'table' => 'clientes', 'alias' => 'Clientes', 'type' => 'INNER', 'conditions' => array( 'Clientes.id_cliente = SenasaPedidos.clientes_id' ) ), ), 'fields'=>array( 'SenasaPedidosFacturadosSds.*', 'Usuarios.usuario_id', 'Usuarios.apellido_nombre', 'Usuarios.senasa_establecimientos_id', 'Clientes.id_cliente', 'Clientes.consolida_doc_sanitaria', 'Clientes.requiere_senasa', 'Clientes.razon_social', 'SenasaPedidos.id', 'SenasaPedidos.domicilio_entrega', 'SenasaPedidos.sds', 'SenasaPedidos.pt_ptr' ), 'conditions'=>array( 'Clientes.requiere_senasa'=>1 ), 'order' => 'SenasaPedidosFacturadosSds.created DESC', 'limit'=>100 ); $this->paginate = $where; // Get datos $data = $this->Paginator->paginate(); exit(debug($data)); 

ИЛИ Пример 2, НЕ активные условия:

 $this->SenasaPedidosFacturadosSds->recursive = -1; // Filtro $where = array( 'joins' => array( array( 'table' => 'usuarios', 'alias' => 'Usuarios', 'type' => 'INNER', 'conditions' => array( 'Usuarios.usuario_id = SenasaPedidosFacturadosSds.usuarios_id' ) ), array( 'table' => 'senasa_pedidos', 'alias' => 'SenasaPedidos', 'type' => 'INNER', 'conditions' => array( 'SenasaPedidos.id = SenasaPedidosFacturadosSds.senasa_pedidos_id' ) ), array( 'table' => 'clientes', 'alias' => 'Clientes', 'type' => 'INNER', 'conditions' => array( 'Clientes.id_cliente = SenasaPedidos.clientes_id', 'Clientes.requiere_senasa = 1' ) ), ), 'fields'=>array( 'SenasaPedidosFacturadosSds.*', 'Usuarios.usuario_id', 'Usuarios.apellido_nombre', 'Usuarios.senasa_establecimientos_id', 'Clientes.id_cliente', 'Clientes.consolida_doc_sanitaria', 'Clientes.requiere_senasa', 'Clientes.razon_social', 'SenasaPedidos.id', 'SenasaPedidos.domicilio_entrega', 'SenasaPedidos.sds', 'SenasaPedidos.pt_ptr' ), //'conditions'=>array( // 'Clientes.requiere_senasa'=>1 //), 'order' => 'SenasaPedidosFacturadosSds.created DESC', 'limit'=>100 ); $this->paginate = $where; // Get datos $data = $this->Paginator->paginate(); exit(debug($data)); 
  $services = $this->Service->find('all', array( 'limit' =>4, 'fields' => array('Service.*','ServiceImage.*'), 'joins' => array( array( 'table' => 'services_images', 'alias' => 'ServiceImage', 'type' => 'INNER', 'conditions' => array( 'ServiceImage.service_id' =>'Service.id' ) ), ), ) ); 

Это goges для array равно null.