Заполнение и связь таблиц.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Заполнение и связь таблиц.

Сообщение Igor346 »

Если пишу не в тот раздел просьба перенести. Необходимо связать две таблицы "Series" и "Colors", связал как hasMany в обоих, по полям color и соответственно id. Одна серия может иметь несколько цветов и один цвет может быть в нескольких сериях. Поле "Color" одно, тип "INT" т.е. могу в него записать только одно числовое значение. Подскажите как правильно оформить выбор нескольких цветов у одной серии?
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Спасибо, почитаю.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Спасибо. Все получилось. Вы большой молодец, что помогаете новичкам, да ещё и таким правильным методом, как первоисточник - прочитав, который надо хоть немного подумать, чтобы все начало работать. Кстати в первоисточнике на мой взгляд (очень новичка), не очень подробно расписано. Из описания сделал вывод, что нужно связать только в одной таблице, а по факту не заработало пока не связал 2 таблицы с промежуточной и не прописал связь в ней с этими двумя таблицами. Я правильно понял или написал чего лишнего? Думаю если бы было расписано максимально подробно, то хуже бы точно не было. Ведь инструкция пишется для новичков, а не профессионалов, которые и так знают, что и как делать.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Заполнение и связь таблиц.

Сообщение girmate »

Более подробно на этом форуме и в Google. Сначала я тоже многое не мог понять. Главное не останавливаться. Чем больше понимаешь как это работает, тем больше удовольствия приносит результат.
Осторожно! Вы общаетесь с новичком ;)
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

girmate писал(а):Более подробно на этом форуме и в Google. Сначала я тоже многое не мог понять. Главное не останавливаться. Чем больше понимаешь как это работает, тем больше удовольствия приносит результат.
Так о чем и речь... :) Главное чтобы в этих поисках ответов не загнать себя в "говнокодеры", хочется учиться писать правильный код. Чтобы со временем не на кодить непотребщины, в которой потом и сам не разберусь.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Заполнение и связь таблиц.

Сообщение girmate »

Igor346 писал(а): Так о чем и речь... :) Главное чтобы в этих поисках ответов не загнать себя в "говнокодеры", хочется учиться писать правильный код. Чтобы со временем не на кодить непотребщины, в которой потом и сам не разберусь.
Я много раз акцентировал свое внимание на этом. Что вроде как и есть собственный код. Но проходит время - смотришь и думаешь как такое можно было написать. А когда смотришь как пишут профессионалы - понимаешь сколько много еще сил нужно чтобы вытворять такие вещи и мыслить также. Но, главное не сдаваться.
Осторожно! Вы общаетесь с новичком ;)
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Заполнение и связь таблиц.

Сообщение Nerf »

Igor346 писал(а):
girmate писал(а):Более подробно на этом форуме и в Google. Сначала я тоже многое не мог понять. Главное не останавливаться. Чем больше понимаешь как это работает, тем больше удовольствия приносит результат.
Так о чем и речь... :) Главное чтобы в этих поисках ответов не загнать себя в "говнокодеры", хочется учиться писать правильный код. Чтобы со временем не на кодить непотребщины, в которой потом и сам не разберусь.
А вы 100% будете говнокодить. Вы учиться собираетесь на форуме или видео-уроки смотреть, а потом раз, два - и в дамки? Нельзя просто взять и начать писать нормальный осознанный код, не набравшись опыта, не пописав вдоволь свои велосипеды.
Конкретно в этой ситуации, дело не в непонятной документации, а в том, что у вас проблемы с основами СУБД (реляционных). Может быть теорию почитать, потом на практику перенести? ;)
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Заполнение и связь таблиц.

Сообщение girmate »

Конечно же, нужно много читать, много практики. Анализировать чужой код. Плюс хорошее знание инструментов, синтаксиса и так далее. Это же очевидно. Но точно знаю, без практики и анализа, самообразования ничего хорошего не достичь. Само оно не придет.
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Заполнение и связь таблиц.

Сообщение ElisDN »

Igor346 писал(а):Кстати в первоисточнике на мой взгляд (очень новичка), не очень подробно расписано... Думаю если бы было расписано максимально подробно, то хуже бы точно не было. Ведь инструкция пишется для новичков, а не профессионалов, которые и так знают, что и как делать.
В инструкции фреймворка написано, как делать связи во фреймворке. Основы о связях написаны в других местах.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Заполнение и связь таблиц.

Сообщение girmate »

ElisDN писал(а): В инструкции фреймворка написано, как делать связи во фреймворке. Основы о связях написаны в других местах.
И не только написаны, а даже показаны: http://www.elisdn.ru/blog/89/related-models-on-yii2 ;)
Осторожно! Вы общаетесь с новичком ;)
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Nerf писал(а):А вы 100% будете говнокодить. Вы учиться собираетесь на форуме или видео-уроки смотреть, а потом раз, два - и в дамки? Нельзя просто взять и начать писать нормальный осознанный код, не набравшись опыта, не пописав вдоволь свои велосипеды.
Конкретно в этой ситуации, дело не в непонятной документации, а в том, что у вас проблемы с основами СУБД (реляционных). Может быть теорию почитать, потом на практику перенести? ;)
Да буду наверное. Куда же от этого денешься? :) Я в самом первом своем посте на этом форуме написал, что у меня нет цели превратить написание кода в заработок, и мой "говнокод" никто по сути и не увидит. С тем, что сначала надо изучить самые азы, тоже спорить не имеет смысла. Я не претендую на позиции равного с опытными программистами, а просто задаю вопросы на которые хочется получить ПРАВИЛЬНЫЕ ответы. Для примера на элементарный вопрос ребенка, взрослому правильнее ответить на понятном ребенку языке или научить делать что попросил ребенок правильно. Я же не задаю вопрос про связь таблиц на форуме любителей охоты на кабана, т.е. люди знают как сделать правильно и могут это рассказать. Также все зарегистрированные здесь участники я Вас уверяю начинали изучать программирование с нуля и даже готов поспорить, что не всегда с четким пониманием того, что дальше делать будет правильно, а что нет. И не поверю, что изучая азы ни разу не забегали вперед и не занимались чем-то неизученным. Так, что демагогию разводить не хочу, тем более не вижу причин. А вот, что Вы имели ввиду говоря "а потом раз два и в дамки" я если честно не понял. А если меня еще и будут посылать в правильном и конкретном направлении за знаниями, то это вообще шоколад. Т.е. в идеале не "в том, что у вас проблемы с основами СУБД (реляционных). Может быть теорию почитать, потом на практику перенести?", а вот здесь поищи: http://bit.ly/2fmeINK ну только ссылку на хороший источник лучше сразу дать. :) Как сделал Дмитрий.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Заполнение и связь таблиц.

Сообщение girmate »

"ПРАВИЛЬНЫЕ ответы" это очень абстрактно. Есть общие тенденции, общепринятые нормы. Существует, как правило, несколько грамотных и красивых решений под любую задачу. Главное, чтобы программа выполняла все заданные функции, была при этом максимально простой и масштабируемой (если планируется развитие).

Типичный пример. Про нормализацию баз данных слышали? Первая нормальная форма, вторая и так далее. Но иногда нужно идти вопреки этих правил - самые часто запрашиваемые данные (главная страница сайта, например), складывают в одну таблицу и затем махом считывается одним запросом. Получается денормализация. Прирост очевидный - вместо 20-30 запросов для главной страницы - всего один - два - три запроса. Периодически, некоторый скрипт "переписывает (обновляет)" эту денормализованную таблицу.

И общий совет. Совет, который касается всех специализированных форумов как этот (из собственного опыта):
1. Изучите, насколько сможете, ту область в которой хотите задать вопрос. В первую очередь изучайте основную документацию.
2. Попробуйте хоть что-то накодить, максимально разобраться самостоятельно.
3. Воспользуйтесь поиском в google, скорее всего вашу задачу уже кто-то решал.
4. Внимательно просканируйте этот форум. Скорее всего, что такой вопрос уже задавался.
5. После пунктов 2-4 снова вернитесь к документации. Иногда шагов 2-4 достаточно, чтобы какой-то кусок информации стал уже более понятен и голове все сложится как надо. Вернитесь к коду, сравните его с другим аналогичным кодом.
6. Напишите и представьте код, если ничего не получилось на этот форум.
7. В теме постарайтесь изложить суть проблемы. Не пишите "HELP! HELP! Все сюда! У меня ошибка". Пишите: "Не считает количество записей в дата провайдере". Позже, это облегчит поиск другим пользоватаелям форума. Еще раз убедитесь, что Ваш вопрос вы задаете в нужной ветке форума. Убедитесь, что нет более подходящих форумов по вашему вопросу. Если вопрос по JS, то не пишите его в ветку "Общие вопросы (Yii 2.x)"

На общие вопросы (как написать сайт) и вопросы не касающиеся общей темы форума никто отвечать не будет. Но при этом будет:
1. Обычный игнор вашей темы
2. Совет поискать на google
3. Грубость в ответ (но это крайне редко, когда ляпните, не подумав)

Все дело в том, что на форуме есть действительно крутые профессионалы. Они реально могут:
- решить любую вашу задачу,
- найти любую вашу ошибку,
- дать дельный совет, поскольку имеют огромный опыт работы.

Но они не будут:
1. Отвечать на слишком простые вопросы. Им это не интересно. Они тоже хотят совершенствоваться. На такие вопросы могут ответить и менее подготовленные пользователи. Или ответят, если им скучно.
2. Писать за вас целые куски кода - модули или всю вашу систему хранения изображений вместе с каруселью.
3. Думать вместо вас, или писать за вас код только потому, что вы радостно сообщили, что вам скинули этот проект и вам некогда с ним разбираться потому что вы ни разу не умеете на yii. Отдайте проект другому программисту, пусть даже за деньги.
4. Отвечать на философские вопросы, или сильно абстрактные вопросы, когда от вас даже невозможно понять что вы хотите.

Если будете соблюдать все, что я вам тут рассказал по секрету, то у вас много шансов получить достойный ответ. Но иногда даже в этом случае бывают осечки. Вы реально можете что-то недопонимать, но не можете сформулировать этот вопрос. Или ваша проблема окажется сильно узкоспециализированной. Малый круг умельцев. И больше никак не получается.

Но! Часто бывает, доходит до смешного. Человек решает проблему большого хранения профилей пользователей в файлах (очень абстарктный пример). И задает много вопросов по ходу: как уменьшить количество файлов, можно ли хранить несколько строк в файлах. Но просто он не знал что существуют базы данных, где это принято хранить в общем случае. Другими словами - часто просят намекнуть для чего вам это нужно, если видят, что какой-то странный вопрос у вас. И предложат нормальное решение, в какую сторону смотреть, если поймут вашу общую задачу. Такие случаи тоже бывают.

P.S. И да, я иногда грешу тем, что не следую вышеописанным правилам. ;)
Всем спасибо.
Осторожно! Вы общаетесь с новичком ;)
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Спасибо, все по делу сказано. Про денормализацию пример очень понравился, но это скорее действительно высший пилотаж, который может прийти в голову человеку более чем понимающему суть вопроса. Я же все-таки пока пытался донести мысль о том, что на "детские" вопросы хочется получать максимально понятные ответы, а вот форма подачи наоборот выбрана правильная, не просто мне сказали своими словами, а отправили к документации после прочтения, которой я еще должен подумать как правильно это использовать. Поэтому как и писал ранее меня все устраивает, коллектив отзывчивый, игнора как такового нет, грубости тем более. Хотя к грубости как к элементу воспитания я отношусь с пониманием у каждого свои методы (главное, чтобы грубость не была самоцелью, это уже к психиатру). В общем за рекомендации благодарю. За сим в данной теме откланяюсь. Ответ дали, опыт мною получен, пожелания высказал, критику выслушал.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Снова возвращаюсь в эту тему со следующей головоломкой. Таблицы посредством промежуточной я связал, если руками в ней проставить значения serie_id и color_id при обращении к colors->name выводится все как надо, а вот если не руками, а через форму при добавлении или изменении серии не соображу как прикрутить, чтобы привязывалось правильно и был множественный выбор. Если не затруднит, подскажите новичку. Заранее благодарен.
geee
Сообщения: 18
Зарегистрирован: 2017.02.19, 18:20

Re: Заполнение и связь таблиц.

Сообщение geee »

Igor346 писал(а): 2017.03.26, 00:14 Снова возвращаюсь в эту тему со следующей головоломкой. Таблицы посредством промежуточной я связал, если руками в ней проставить значения serie_id и color_id при обращении к colors->name выводится все как надо, а вот если не руками, а через форму при добавлении или изменении серии не соображу как прикрутить, чтобы привязывалось правильно и был множественный выбор. Если не затруднит, подскажите новичку. Заранее благодарен.
В смысле выбор цвета при добавлении серии? Если да, то просто достаете все цвета из БД, передаете их в вид где форма генерируется и выводите их циклом в select или multiple select (если нужно чтобы несколько цветов выбирать можно было).
Ну и вот еще https://github.com/yiisoft/yii2/blob/ma ... %86%D1%8B-
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

geee писал(а): 2017.03.26, 01:17 В смысле выбор цвета при добавлении серии? Если да, то просто достаете все цвета из БД, передаете их в вид где форма генерируется и выводите их циклом в select или multiple select (если нужно чтобы несколько цветов выбирать можно было).
Да, выбор цвета при добавлении или изменении серии. Пока не совсем понял, но утром буду пытаться. Вам спасибо за подсказку.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Не могу пока сообразить как все-таки реализовать, написанное Вами. Ссылку на связную таблицу я прочитал, и как и писал ранее понял, как это сделать при добавлении руками в таблицы, а вот как через форму добавления не знаю.
Не могу в контроллере достать цвета из таблицы Colors (только цвет текущей серии при редактировании через $model->colors)
Понимаю, что код белиберда, но если не затруднит помогите восполнить пробелы в знаниях, путем выявления ошибок и пояснения как правильно.

Сейчас у меня:
Модель Series

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

<?php

namespace app\modules\secret\models;

use Yii;
use app\models\CategoriesPrice;
use app\models\Styles;
use app\models\Country;
use app\models\Colors;
use app\models\SeriesColor;



/**
 * This is the model class for table "series".
 *
 * @property integer $id
 * @property string $keywords
 * @property string $description
 * @property string $name
 * @property integer $category_id
 * @property integer $color
 * @property integer $category_price
 * @property string $material
 * @property integer $style
 * @property string $thickness
 * @property integer $country
 * @property string $img
 */
class Series extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'series';
    }


    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['category_id', 'keywords', 'description', 'content', 'material', 'thickness'], 'string'],
            [['name', 'category_id', 'color', 'category_price', 'material', 'style', 'countries'], 'required'],
            [['color', 'category_price', 'style', 'countries'], 'integer'],
            [['name'], 'string', 'max' => 80],
            [['img'], 'string', 'max' => 200],
        ];
    }

    public function getCategories()
    {
        return $this->hasOne(Categories::className(), ['id' => 'category_id']);
    }

    public function getCategoriesPrice()
    {
        return $this->hasOne(CategoriesPrice::className(), ['id' => 'category_price']);
    }

    public function getStyles()
    {
        return $this->hasOne(Styles::className(), ['id' => 'style']);
    }

    public function getCountry()
    {
        return $this->hasOne(Country::className(), ['id' => 'countries']);
    }

    public function getSeriesColor()
    {
        return $this->hasMany(SeriesColor::className(), ['serie_id' => 'id']);
    }

    public function getColors()
    {
        return $this->hasMany(Colors::className(), ['id' => 'color_id'])->via('seriesColor');
    }
    
    

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => '№',
            'keywords' => 'Ключевики',
            'description' => 'Мета описание',
            'content' => 'Описание серии',
            'name' => 'Название',
            'category_id' => 'Категория',
            'color' => 'Цвет',
            'category_price' => 'Ценовая категория',
            'material' => 'Используемые материалы',
            'style' => 'Стиль',
            'thickness' => 'Толщина деталей',
            'countries' => 'Страна производства',
            'img' => 'Картинка',
        ];
    }
}

Контроллер

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

<?php

namespace app\modules\secret\controllers;


use Yii;
use app\models\Colors;
use app\modules\secret\models\Series;
use yii\data\ActiveDataProvider;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
 * SeriesController implements the CRUD actions for Series model.
 */



class SeriesController extends Controller
{
    /**
     * @inheritdoc
     */
    
    
    
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Lists all Series models.
     * @return mixed
     */



    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Series::find()->with('categories', 'colors'),
        ]);

        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single Series model.
     * @param integer $id
     * @return mixed
     */
    
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new Series model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new Series();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->session->setFlash('info', "Серия {$model->name} создана.");
            return $this->redirect(['view', 'id' => $model->id]);
        } else {

//            Yii::$app->session->setFlash('info', 'Ошибка');
            
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Updates an existing Series model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->session->setFlash('info', "Серия {$model->name} обновлена.");
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Deletes an existing Series model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
        Yii::$app->session->setFlash('info', "Серия {$model->name} удалена.");
        return $this->redirect(['index']);
    }

    /**
     * Finds the Series model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Series the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Series::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
    
    
    
}
Форма

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

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\modules\secret\models\Categories;
use app\models\Colors;
use app\models\CategoriesPrice;
use app\models\Country;
use app\models\Styles;
/* @var $this yii\web\View */
/* @var $model app\modules\secret\models\Series */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="series-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= debug($colors) ?>

    <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'content')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'keywords')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'category_id')->dropDownList(ArrayHelper::map(Categories::find()->all(), 'id', 'name')) ?>

    <?= $form->field($model, 'category_price')->dropDownList(ArrayHelper::map(CategoriesPrice::find()->all(), 'id', 'name')) ?>

    <div class="form-group field-series-color required has-success">
        <label class="control-label" for="colors-name">Цвет</label>
        <select id="colors-name" class="selectpicker" multiple>
            <option><? foreach ($model->colors as $color):?><?= $color->name ?><? endforeach;?></option>
        </select>
    </div>


    <?= $form->field($model, 'material')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'thickness')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'style')->dropDownList(ArrayHelper::map(Styles::find()->all(), 'id', 'name')) ?>

    <?= $form->field($model, 'countries')->dropDownList(ArrayHelper::map(Country::find()->all(), 'id', 'name')) ?>

    <?= $form->field($model, 'img')->textInput(['maxlength' => true]) ?>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Создать' : 'Обновить', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>
Последний раз редактировалось Igor346 2017.03.31, 15:45, всего редактировалось 1 раз.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Немного сдвинулся с мертвой точки, а именно удалось получить таблицу цветов не совсем привычным способом, в виде

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

<div class="form-group field-series-color  required has-success">
        <label class="control-label" for="series-color">Цвет</label><br>
        <select id="series-color" class="selectpicker" multiple>
            <? foreach (Colors::find()->all() as $color):?><option><?= $color->name ?></option><? endforeach;?>
        </select>


    </div>
в контроллере же так и не смог. Но полученный результат дает совсем не тот эффект, на который я рассчитываю. Цвета я выбрать могу, но они не переписываются в таблице.
Igor346
Сообщения: 87
Зарегистрирован: 2016.09.13, 22:59

Re: Заполнение и связь таблиц.

Сообщение Igor346 »

Подскажите пожалуйста, как правильно сделать.
Ответить