Здравствуй,
Мне нужно выполнить следующий запрос с помощью метода 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.
Вы должны создать связь с моделью пользователя и моделью сообщений и использовать сдерживаемое поведение:
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 поддерживает синтаксис для определения ваших собственных соединений. Это будет сделано с помощью 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.