Как организовать хранение файлов?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.03, 17:17

У меня в общем случае для загружаемых файлов есть моделька вида files(id, path, original_name, is_deleted, created_at, updated_at), но к этой модельке по мере необходимости добавляются некоторые поля, исключительные для конкретного случая (в основном связи), например article_id или payment_id. Таким образом в базе у меня получается по таблице для каждого такого случая. Мне это не нравится. Получается какое-то дублирование... Как это лучше организовать? Чтобы все основные данные о файлах были в одной таблице, а уже отдельно как-то то что касается конкретной реализации. Ну например будет article_files(id, article_id), но как мне в этом случае реализовать саму модель в Yii? Там же указывается в tableName только одна таблица. Нельзя указать связь в качестве таблицы.

Wizard
Сообщения: 173
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Как организовать хранение файлов?

Сообщение Wizard » 2018.09.03, 19:13

Brainfuck писал(а):
2018.09.03, 17:17
У меня в общем случае для загружаемых файлов есть моделька вида files(id, path, original_name, is_deleted, created_at, updated_at), но к этой модельке по мере необходимости добавляются некоторые поля, исключительные для конкретного случая (в основном связи), например article_id или payment_id. Таким образом в базе у меня получается по таблице для каждого такого случая. Мне это не нравится. Получается какое-то дублирование... Как это лучше организовать? Чтобы все основные данные о файлах были в одной таблице, а уже отдельно как-то то что касается конкретной реализации. Ну например будет article_files(id, article_id), но как мне в этом случае реализовать саму модель в Yii? Там же указывается в tableName только одна таблица. Нельзя указать связь в качестве таблицы.
в любом случае от дополнительных таблиц или колонок в одной общей не избавиться

если у статьи и других сущностей есть файлы, которые хранятся в одной таблице просто добавьте к примеру колонку entity и entity_id

в качестве entity Model:class
Последний раз редактировалось Wizard 2018.09.03, 19:19, всего редактировалось 3 раза.

Wizard
Сообщения: 173
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Как организовать хранение файлов?

Сообщение Wizard » 2018.09.03, 19:16

возможно то что вам необходимо это - Полиморфные отношения

Полиморфные отношения позволяют модели быть связанной с более чем одной моделью

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.04, 09:17

Wizard писал(а):
2018.09.03, 19:13
в любом случае от дополнительных таблиц или колонок в одной общей не избавиться
Как это не избавиться? Вы меня наверное неправильно поняли. Еще раз. Сейчас у меня так: article_files(id, article_id, path, original_name...), payment_files(id, payment_id, path, original_name...) и т.д. Я хочу чтобы было так: files(id, path, original_name...), article_files(id, article_id) - где article_files.id это ссылка на files.id.
Wizard писал(а):
2018.09.03, 19:13
если у статьи и других сущностей есть файлы, которые хранятся в одной таблице просто добавьте к примеру колонку entity и entity_id

в качестве entity Model:class
Не понял что вы имели ввиду.
Wizard писал(а):
2018.09.03, 19:16
возможно то что вам необходимо это - Полиморфные отношения

Полиморфные отношения позволяют модели быть связанной с более чем одной моделью
Тоже не особо понял о чем речь. Вы о связи один ко многим и ленивой загрузке? Вообще это идея... Т.е. все модели (article_files, payment_files...) будут иметь одну общую таблицу files (она же будет указана методом tableName), но будут иметь разные отношения, которые через эти доп. таблицы будут получать ссылку на статью/платеж и т.п. Правда я плохо понимаю как я буду добавлять связи... Мне что будет нужна отдельная моделька для этого?

Вот например:

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

/**
 * @property-read Article $article
 */
class ArticleFile extends FileBase {
    public static function tableName() {
        return '{{%files}}';
    }

    public function getArticle() {
	// что тут писать??? Таким образом я получу не статью, а строку из таблицы связей
        return $this->hasOne('{{%article_files}}', ['id' => 'id']);
    }
}

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.10, 11:11

Вопрос все еще актуален!!!

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как организовать хранение файлов?

Сообщение andku83 » 2018.09.10, 12:19

Выполняем миграцию:

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

    public function safeUp()
    {
        $this->createTable('{{%files}}', [
            'id' => $this->primaryKey(),
            'path' => $this->string(),
            'original_name' => $this->string(),
            'is_deleted' => $this->boolean(),
            'created_at' => $this->integer(),
            'updated_at' => $this->integer(),
        ]);
        $this->createTable('{{%articles}}', [
            'id' => $this->primaryKey(),
            'name' => $this->string(),
            'text' => $this->text(),
            'is_deleted' => $this->boolean(),
            'created_at' => $this->integer(),
            'updated_at' => $this->integer(),
        ]);
        $this->createTable('{{%article_file}}', [
            'id' => $this->integer(),
            'article_id' => $this->integer(),
        ]);
        
        $this->addPrimaryKey('pk-article_file', '{{%article_file}}', ['id', 'article_id']);

        $this->addForeignKey('fk-article_file-file_id', '{{%article_file}}', 'id', '{{%files}}', 'id', 'cascade', 'cascade');
        $this->addForeignKey('fk-article_file-article_id', '{{%article_file}}', 'article_id', '{{%articles}}', 'id', 'cascade', 'cascade');
    }
Заходим в gii, генерируем модельки, смотрим что получилось.
Последний раз редактировалось andku83 2018.09.18, 12:41, всего редактировалось 1 раз.

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.10, 12:30

andku83 писал(а):
2018.09.10, 12:19
Я неплохо и сам умею делать миграции. Не надо мне кидать любую дичь. Сначала почитайте тему.

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как организовать хранение файлов?

Сообщение andku83 » 2018.09.10, 13:05

Ну раз вы умеете делать миграции - делайте, просите советов - не слушаете, ждите "манны небесной", не буду вам мешать...

Аватара пользователя
carono
Сообщения: 52
Зарегистрирован: 2018.04.28, 11:05

Re: Как организовать хранение файлов?

Сообщение carono » 2018.09.11, 22:00

сделайте сводную таблицу, в которой будет 2 поля, (article_id, files_id) сделайте один PK ключ на два поля, внешние ключи повесьте и сгенерируйте через gii, как предлагали выше, тогда у вас в модели article сгенерируется релашка getFiles() сразу на ваши модели файлов через via

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

class Article extends ActiveRecord {
	public function getFiles()
	{
		return $this->hasMany(\app\models\Files::className(), ['id' => 'files_id'])->viaTable('{{%pv_article_files}}', ['article_id' => 'id']);
	}
}	

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.17, 17:53

carono писал(а):
2018.09.11, 22:00
сделайте сводную таблицу, в которой будет 2 поля, (article_id, files_id) сделайте один PK ключ на два поля, внешние ключи повесьте и сгенерируйте через gii, как предлагали выше, тогда у вас в модели article сгенерируется релашка getFiles() сразу на ваши модели файлов через via

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

class Article extends ActiveRecord {
	public function getFiles()
	{
		return $this->hasMany(\app\models\Files::className(), ['id' => 'files_id'])->viaTable('{{%pv_article_files}}', ['article_id' => 'id']);
	}
}	
Тогда уж \app\models\ArticleFile (он будет ссылаться на ту же общую таблицу файлов). Но я не знаю как из этого самого ArticleFile получить ссылку на статью. Как будет выглядеть эта релашка?

Аватара пользователя
carono
Сообщения: 52
Зарегистрирован: 2018.04.28, 11:05

Re: Как организовать хранение файлов?

Сообщение carono » 2018.09.17, 19:10

Сводная таблица файлов и статей {{%article_file}} чтобы из неё получить релашку на файл или статью

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

class ArticleFile extends ActiveRecord {
	public function getArticle()
	{
		return $this->hasOne(\app\models\Article::className(), ['id' => 'articles_id']);
	}


	/**
	 * @return \app\models\query\FileQuery|\yii\db\ActiveQuery
	 */
	public function getFile()
	{
		return $this->hasOne(\app\models\Files::className(), ['id' => 'files_id']);
	}
}
Чтобы получить все статьи, через таблицу с файлами

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

class Files extends ActiveRecord {
	public function getArticles()
	{
		return $this->hasMany(\app\models\Article::className(), ['id' => 'articles_id'])->viaTable('{{%article_file}}', ['files_id' => 'id']);
	}
}

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.18, 09:34

carono писал(а):
2018.09.17, 19:10
Метод getArticle не будет работать, т.к. в этой таблице нет article_id. Вы меня опять не так поняли, хотя я подробно объяснял и приводил код.

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

class File extends FileBase {
	public static function tableName() {
        return '{{%files}}';
    }
}

class ArticleFile extends FileBase {
}
Модель ArticleFile должна наследоваться от ArticleFile чтобы иметь все свойства обычного файла, но дополнительно каким-то образом подтягивать article_id из связанной таблицы article_files.

У вас какая-то странная странная стратегия именования. Модель не должна называться Files. File - в единственном числе. А вот таблица в базе может называться во множественном числе - files/article_files и имхо так лучше. И не articles_id, а article_id - тоже в ед. числе.

Аватара пользователя
carono
Сообщения: 52
Зарегистрирован: 2018.04.28, 11:05

Re: Как организовать хранение файлов?

Сообщение carono » 2018.09.18, 09:50

какие проблемы использовать генератор gii?если структуру сделал верно, то у тебя все сгенерится. Я никогда не прописываю релашки, занятие лишнее, если все ключи расставлены верно.
Последний раз редактировалось carono 2018.09.18, 09:52, всего редактировалось 1 раз.

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.18, 09:52

carono писал(а):
2018.09.18, 09:50
какие проблемы использовать генератор gii?если структуру сделал верно, то у тебя все сгенерится.
Я никогда не использую gii принципиально. Предпочитаю иметь больше контроля. К тому же что может сгенерировать какой-то скрипт если я сам еще не понимаю как это должно выглядеть?

Аватара пользователя
carono
Сообщения: 52
Зарегистрирован: 2018.04.28, 11:05

Re: Как организовать хранение файлов?

Сообщение carono » 2018.09.18, 09:58

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

Аватара пользователя
carono
Сообщения: 52
Зарегистрирован: 2018.04.28, 11:05

Re: Как организовать хранение файлов?

Сообщение carono » 2018.09.18, 10:07

Глянь на эту схему, релашки что я скидывал ранее, для неё
Изображение

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как организовать хранение файлов?

Сообщение andku83 » 2018.09.18, 11:31

carono писал(а):
2018.09.18, 10:07
Глянь на эту схему, релашки что я скидывал ранее, для неё
...
я выше писал миграцию с подобной структурой и получил ответ:
Brainfuck писал(а):
2018.09.10, 12:30
Я неплохо и сам умею делать миграции. Не надо мне кидать любую дичь. Сначала почитайте тему.
так что человек либо хочет чтоб ему "разжевали" каждую буковку или просто не пытается понять сказанного...

дополнил в миграцию:

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

        $this->addPrimaryKey('pk-article_file', '{{%article_file}}', ['id', 'article_id']);
благодаря этому gii добавляет еще одну связь через ->viaTable(),
для красоты кода можно вместо ->viaTable() использовать ->via('relationName')

@2topicStarter
погляди внимательно видео и тогда (возможно) поймешь что тебе говорят.

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.18, 14:44

carono писал(а):
2018.09.18, 09:58
я тебе написал, что для сводной таблицы многие-ко-многим нужно сделать первичный ключ на два поля. Ни кто ни от чего наследоваться не должен, у тебя есть таблица со статьями, таблица где хранятся файлы и отдельная сводная таблица.
Ты понимаешь что само сочетание $articleFile->getFile() звучит как полный абсурд? Это не логично. Из файла получать файл. Тогда надо хотя-бы как-то поиграться с названиями моделей чтобы это выглядело более логично, но я не знаю как по другому это обозвать. Куда логичнее наследоваться.
carono писал(а):
2018.09.18, 10:07
Глянь на эту схему, релашки что я скидывал ранее, для неё
Все верно. Я говорил именно о такой схеме.
andku83 писал(а):
2018.09.18, 11:31
так что человек либо хочет чтоб ему "разжевали" каждую буковку или просто не пытается понять сказанного...
Почему ты все время пытаешься меня оскорбить? Я отлично разбираюсь в этом фреймворке. Не надо мне приводить очевидные вещи. Я просто не знаю конкретно как сделать то что я описал. Видимо никак. Буду как и раньше плодить таблицы файлов с одинаковыми полями.

P.S. Мне не нужна миграция черт возьми. Я знаю как будет выглядеть схема. Человек выше привел ее совершенно верно - как я и хочу. Я не знаю лишь как реализовать модели в данном случае и чертов богомерзкий gii тут вообще не причем. gii нужен для ускорения процесса когда ты знаешь как должен выглядеть код и можешь его написать сам.
Последний раз редактировалось Brainfuck 2018.09.18, 14:49, всего редактировалось 2 раза.

Brainfuck
Сообщения: 260
Зарегистрирован: 2018.02.19, 14:20

Re: Как организовать хранение файлов?

Сообщение Brainfuck » 2018.09.18, 15:09

Вообще вы мне все-таки подали идею которую я смог развить вот во что:

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

class File extends FileBase {
	public static function tableName() {
        return '{{%files}}';
    }
}

class ArticleFile extends FileBase {
	public function getArticle() {
		return $this->hasOne(Article::class, ['id' => 'article_id'])->viaTable('article_files', ['file_id' => 'id']);
	}
}
Схема та же что приводили выше. Как думаете проканает? Сейчас буду тестить...

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как организовать хранение файлов?

Сообщение andku83 » 2018.09.18, 15:14

если можно, покажи где я пытался оскорблять.
Brainfuck писал(а):
2018.09.10, 12:30
... Не надо мне кидать любую дичь. Сначала почитайте тему.
Brainfuck писал(а):
2018.09.18, 14:44
... чертов богомерзкий gii тут вообще не причем. gii нужен для ускорения процесса когда ты знаешь как должен выглядеть код и можешь его написать сам.
а вот это как раз похоже на оскорбление и не только меня а и разработчиков gii.

Закрыто