Страница 1 из 2

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

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

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

Добавлено: 2018.09.03, 19:13
BalykhinAS
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

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

Добавлено: 2018.09.03, 19:16
BalykhinAS
возможно то что вам необходимо это - Полиморфные отношения

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

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

Добавлено: 2018.09.04, 09:17
Brainfuck
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']);
    }
}

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

Добавлено: 2018.09.10, 11:11
Brainfuck
Вопрос все еще актуален!!!

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

Добавлено: 2018.09.10, 12:19
andku83
Выполняем миграцию:

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

    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, генерируем модельки, смотрим что получилось.

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

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

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

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

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

Добавлено: 2018.09.11, 22:00
carono
сделайте сводную таблицу, в которой будет 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']);
	}
}	

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

Добавлено: 2018.09.17, 17:53
Brainfuck
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 получить ссылку на статью. Как будет выглядеть эта релашка?

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

Добавлено: 2018.09.17, 19:10
carono
Сводная таблица файлов и статей {{%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']);
	}
}

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

Добавлено: 2018.09.18, 09:34
Brainfuck
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 - тоже в ед. числе.

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

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

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

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

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

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

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

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

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

Добавлено: 2018.09.18, 11:31
andku83
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
погляди внимательно видео и тогда (возможно) поймешь что тебе говорят.

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

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

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

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

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

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

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']);
	}
}
Схема та же что приводили выше. Как думаете проканает? Сейчас буду тестить...

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

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