Очередной вопрос новичка по JOIN

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Очередной вопрос новичка по JOIN

Сообщение miken »

Просмотрел тут темы по JOIN так и не понял как решить вот такой вопрос. Есть у меня 2 таблицы orders и users, через gii создал для таблицы orders модели, контролеры и виды.
Все данные прекрасно отображаются, но мне нужно что чтобы показывались определенные поля и 2 таблиц объединенных через LEFT join
SELECT `store_number`, `o_date`, `order_id`, `contact_name`, `usertype`, `org`, `user_id`,
FROM `orders` LEFT join `users` ON `orders` .`user_id`=`users`.id
предположил что в контроллере надо переделать $query = Orders::find()

Код: Выделить всё

$query = Orders::find()
                    ->leftJoin('users','orders.user_id=users_.id')
                    ->orderBy(['o_date' => SORT_DESC, 'store_number' => SORT_DESC])
                    ->where(['store_number'=>':0']);
Вроде никаких ошибок нет. Кроме того что в debug запрос выглядит как то не так.

Код: Выделить всё

SELECT  `orders` . * 
FROM  `orders` 
LEFT JOIN  `users` ON orders.user_id = users.id
WHERE  `store_number` =  ':0'
ORDER BY  `o_date` DESC ,  `store_number` DESC 
LIMIT 20
То есть он выбирает только поля одной таблицы. Поиск по форума дал вариант что надо добавить в select

Код: Выделить всё

$query = Orders::find()->select('orders.* , users.*')
                    ->leftJoin('users','orders.user_id=users_.id')
                    ->orderBy(['o_date' => SORT_DESC, 'store_number' => SORT_DESC])
                    ->where(['store_number'=>':0']);
В дебаг запрос стал более похож на то что нужно

Код: Выделить всё

SELECT  `orders` . *,`users` . * 
FROM  `orders` 
LEFT JOIN  `users` ON orders.user_id = users.id
WHERE  `store_number` =  ':0'
ORDER BY  `o_date` DESC ,  `store_number` DESC 
LIMIT 20

И работает вроде как без ошибок. НО при попытке добавить в вид вывод поля например usertype из таблицы users
получаю
Unknown Property – yii\base\UnknownPropertyException

Getting unknown property: backend\models\OrdersSearche::usertype

Код: Выделить всё

 <?php echo GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'order_id',
            'user_id',
            'store_number',
            'delivery',
            'o_date',
        'usertype',    
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
Очень буду благодарен если с примерами расскажите как решить такую простую задачку?
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

Для начала стоит разобраться, зачем вы делаете в пределах фреймворка JOIN, если есть Relations.
И этот инструмент (Relation) тут явно подходит больше, нежели ручной JOIN.
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение yiijeka »

'users.usertype'
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

Я только начала изучение YII. А про relation nsn переодически упоминают но примеров найти не удалось.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

yiijeka писал(а):'users.usertype'
Так тоже не работает.
Unknown Property – yii\base\UnknownPropertyException

Getting unknown property: backend\models\Orders::users
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

miken писал(а):Я только начала изучение YII. А про relation nsn переодически упоминают но примеров найти не удалось.
(:

https://github.com/yiisoft/yii2/blob/ma ... onal-data-

Это пробовали читать?
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

rugabarbo писал(а):
miken писал(а):Я только начала изучение YII. А про relation nsn переодически упоминают но примеров найти не удалось.
(:

https://github.com/yiisoft/yii2/blob/ma ... onal-data-

Это пробовали читать?
Пробовал. отсюда и брал ->leftJoin :)

про relation там тоже было, но пример совсем непонятен. Поэтом искал примеры более понятные и не нашел
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

miken писал(а):
rugabarbo писал(а):
miken писал(а):Я только начала изучение YII. А про relation nsn переодически упоминают но примеров найти не удалось.
(:

https://github.com/yiisoft/yii2/blob/ma ... onal-data-

Это пробовали читать?
Пробовал. отсюда и брал ->leftJoin :)

про relation там тоже было, но пример совсем непонятен. Поэтом искал примеры более понятные и не нашел
Вы же работаете с реляционной моделью данных. Так разберитесь, каким образом реляции можно отражать на уровень кода в фреймворке, иначе у вас будут проблемы. Вы постоянно будете городить JOIN-ы вместо использования реляций, что приведёт к плачевным последствиям.

С таким же успехом можно вместо ActiveRecord использовать в контроллерах QueryBuilder. Только проще всё же разобраться один раз с AR.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

я и хочу разобраться. но примера из документации мне не достаточно. хотелось бы более простым языком
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

miken писал(а):я и хочу разобраться. но примера из документации мне не достаточно. хотелось бы более простым языком
miken, так не пойдёт (: Вы напишите, что именно не получилось, дайте НЕработающие примеры кода, но свои.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

rugabarbo писал(а):
miken писал(а):я и хочу разобраться. но примера из документации мне не достаточно. хотелось бы более простым языком
miken, так не пойдёт (: Вы напишите, что именно не получилось, дайте НЕработающие примеры кода, но свои.
Я же писал выше примеры того что нагородил. И ошибки которые пишет. Я не прошу готовое решение. Мне просто нужен пример(не обязательно код) того как должна решаться такая задача. Что то типа создаем в модели 2 класс для 2 таблиц, а дальше к ним обращаемся через что-то. К сожалению о что описано в документации не дает наглядности в решение.
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

Попробуйте разобраться на примере сортировки, фильтрации и отображения реляций в GridView: http://www.yiiframework.com/wiki/653/di ... -gridview/

Подойдёт такой пример? Мне кажется он достаточно наглядный.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

rugabarbo писал(а):Попробуйте разобраться на примере сортировки, фильтрации и отображения реляций в GridView: http://www.yiiframework.com/wiki/653/di ... -gridview/

Подойдёт такой пример? Мне кажется он достаточно наглядный.
тут немного понятнее. Но все же есть вопросы.

1.

Код: Выделить всё

/**
 * @return \yii\db\ActiveQuery */
public function getCountry()
{
    return $this->hasOne(Country::className(), ['id' => 'country_id']);
}
 
/**
 * @return \yii\db\ActiveQuery */
public function getCity()
{
    return $this->hasOne(City::className(), ['id' => 'city_id']);
} 


Это я как понял вписываю в модель orders. Но не ясна конструкция Country::className() - Country это что? оно где то должно быть прописан? то есть создана модель или как?

просто если я вписываю это в модель но со своими наименованиями

Код: Выделить всё

class UserOrders extends \yii\db\ActiveRecord
{
    
        /**
         * @return \yii\db\ActiveQuery */
        public function getOrders()
        {
            return $this->hasOne(UserOrders::className(), ['id' => 'order_id']);
        }
         
        /**
         * @return \yii\db\ActiveQuery */
        public function getUsers()
        {
            return $this->hasOne(Users::className(), ['id' => 'user_id']);
        }
    
     
То получаю ошибку:
PHP Fatal Error – yii\base\ErrorException

Class 'backend\models\Users' not found
Понимаю что класс не задан. Где должен быть этот класс?
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

Создал модель по таблице users отдельно через gii

Запустил получил уже другую ошибку:

Код: Выделить всё

Database Exception – yii\db\Exception

SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'orders'
The SQL being executed was: SELECT COUNT(*) FROM `orders` LEFT JOIN `orders` ON `orders`.`order_id` = `orders`.`id` LEFT JOIN `users` ON `orders`.`user_id` = `users`.`id`
Error Info: Array
(
    [0] => 42000
    [1] => 1066
    [2] => Not unique table/alias: 'orders'
)
Видно что запрос какой-то странный. и как он таким получился не поняно
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: Очередной вопрос новичка по JOIN

Сообщение mkramer »

Эм, а вы с PHP-то дружите? Пространства имён понимаете? Статический метод className() возвращает полное имя класса (со всеми пространствами имён), поскольку при косвенном вызове (например, через call_user_func) все ваши use игнорируются. А последнюю ошибку прочитать пробовали - у вас orders сама с собой связывается зачем-то, база и не может понять, что к чему.

Чтоб разобраться, давайте с ваших таблиц начнём. Какие у вас таблицы, какие между ними связи?
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

mkramer писал(а):Эм, а вы с PHP-то дружите? Пространства имён понимаете? Статический метод className() возвращает полное имя класса (со всеми пространствами имён), поскольку при косвенном вызове (например, через call_user_func) все ваши use игнорируются. А последнюю ошибку прочитать пробовали - у вас orders сама с собой связывается зачем-то, база и не может понять, что к чему.

Чтоб разобраться, давайте с ваших таблиц начнём. Какие у вас таблицы, какие между ними связи?
1. Дружу дружу :D но обычно только с джумлой и некоторым самописными движками. Но сейчас не об этом.
2. Давайте разберемся

Таблица users

Код: Выделить всё

id
Name
meta
type
Таблица orders

Код: Выделить всё

orders_id
users_id
store_number
delivery
o_date
orders.user_id=users.id

как то так.
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

orders_id - это PK в таблице orders или нет?

Честно говоря, в БД у вас трэш:
* таблицы во множественном числе
* поле users.Name почему-то с большой буквы
* в users PK объявлен без префикса (users.id), а в orders с префиксом (orders.orders_id)
* насколько я понимаю, одна запись в orders - это один заказ одного пользователя, но именование ID-шников множественное (orders_id, users_id)
* я бы мог и дальше продолжать, но мне лень...

База - это основа приложения. Если в ней трэш, то в приложении и подавно будет трэш.
miken
Сообщения: 33
Зарегистрирован: 2015.05.20, 12:46

Re: Очередной вопрос новичка по JOIN

Сообщение miken »

rugabarbo писал(а):orders_id - это PK в таблице orders или нет?

Честно говоря, в БД у вас трэш:
* таблицы во множественном числе
* поле users.Name почему-то с большой буквы
* в users PK объявлен без префикса (users.id), а в orders с префиксом (orders.orders_id)
* насколько я понимаю, одна запись в orders - это один заказ одного пользователя, но именование ID-шников множественное (orders_id, users_id)
* я бы мог и дальше продолжать, но мне лень...

База - это основа приложения. Если в ней трэш, то в приложении и подавно будет трэш.
Так база в таком виде перешла по наследству, тут в ней много странностей и похлеще этого.

В таблице orders нету Primary key вообще.

Ода запись в orders соотвествует одному users. но записей у одного пользователя может быть много в таблице orders


Не сраpу понял про множественное:)

вот так правильно:

Orders:

Код: Выделить всё

    1    order_id    int(10)
    2    user_id    int(10)    
    3    store_order_id    varchar(255)    
    4    store_number    int(11)        
    5    delivery    varchar(255)
    6    o_date    datetime
Последний раз редактировалось miken 2015.06.23, 21:32, всего редактировалось 1 раз.
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: Очередной вопрос новичка по JOIN

Сообщение mkramer »

Я просил написать тип связи между таблицами (один-к-одному, один-ко-многим, многие-ко-многим). И если orders_id - это не PK, то как один заказ отличается от другого?
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Очередной вопрос новичка по JOIN

Сообщение rugabarbo »

Так база в таком виде перешла по наследству, тут в ней много странностей и похлеще этого.
В таблице orders нету Primary key вообще.
Сочувствую.

Мне не хочется разбираться в этом хламе, поэтому я буду исходить из предположения, что есть таблица user: И таблица order:

Код: Выделить всё

id
user_id
store_number
Соответственно, ORM для них: User и Order

Теперь в класс Order встроим код:

Код: Выделить всё

class Order extends ActiveRecord
{ 
    ...

    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }

    ...
} 
Теперь в любой найденной модели Order можно будет получить доступ к связной модели User так:

Код: Выделить всё

$user = $order->user; 
Или же можно сразу вытащить идентификатор пользователя так:

Код: Выделить всё

$userID = $order->user->id; 
Соответственно в GridView со списком заказов можно будет использовать колонку:

Код: Выделить всё

[
    'label'     => 'ID пользователя, сделавшего заказ',
    'attribute' => 'user.id',
], 
Как-то так. Отразить это на ваши реалии - ваша задача.
Последний раз редактировалось rugabarbo 2015.06.23, 21:37, всего редактировалось 1 раз.
Ответить