Всем привет, кто читает мою статью.
Создадим проект, начальную базу для дальнейшей работы. Используемые программные средства:
• IDE — Sublime Text.
• Laragon Wamp 4.0.
• Git.
• Laravel 5.5.
• Bootstrap 4.
Используемые дополнительные библиотеки:
• laravelcollective/html — v 5.4.
• intervention/image — v 2.4.
• stechstudio/laravel-php-cs-fixer — v 1.0.
Так же при написании проекта в помощь будем использовать:
• «Хорошие практики Laravel».
Далее выполняем пункт 1 тестового задания — ничего сложного:
— Модель User без кастомных полей.
Создаются по умолчанию миграции.
— Модель Article с полем text.
Создаем миграцию:
- php artisan make:migration CreateArticlesTable --create=articles
В созданной миграции в методе up() опишем создаваемые поля:
class CreateArticlesTable extends Migration
{
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->default('none');
$table->string('text');
$table->timestamps();
});
}
...
}
После этого применяем наши миграции:
- php artisan migrate
— Относятся как многие ко многим.
Т.к. отношение многие ко многим, то для начала создадим дополнительную таблицу «article_user» в БД :
- php artisan make:migration CreateArticleUserTable --create=article_user
В созданной миграции в методе up() опишем создаваемые поля необходимые для отношения многие ко многим:
class CreateArticleUserTable extends Migration
{
public function up()
{
Schema::create('article_user', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id')->default(1);
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedInteger('article_id')->default(1);
$table->foreign('article_id')->references('id')->on('articles');
$table->timestamps();
});
}
...
}
— Написать свойство articles в первой модели, которое вернёт все статьи пользователя.
Добавляем метод articles в нашу модель User:
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password'
];
protected $hidden = [
'password', 'remember_token',
];
public function articles()
{
return $this->belongsToMany('App\Article', 'article_user')->withTimestamps();
}
...
}
— Написать метод users во второй, который вернёт всех авторов статьи.
Здесь необходимо создать модель Articles.
- php artisan make:model Article
Уже после этого добавляем свойство users:
class Article extends Model
{
protected $fillable = [
'id', 'text', 'title', 'created_at'
];
public function users()
{
return $this->belongsToMany('App\User', 'article_user')->withTimestamps();
}
...
}
А вот наши методы в действии (соответственно):
user_articles.blade.php
<div class="main-content">
<article>
<h2 class="page-title">{{ $title }}: {{ $user->name }}</h2>
<p>
<a href="{{ route('home') }}" class="btn btn-default btn-sm btn-back" type="button">{{ __('site.but_return_main') }}</a>
</p>
</article>
@if ($user->articles)
@foreach ($user->articles as $article)
<article>
<a href="{{ route('articles.show', $article->id) }}"><h2 class="post-title">{{ $article->title }}</h2></a>
<div class="post-meta">
@foreach ($article->users as $user)
<span><a href="{{ route('authors.articles',$user->id) }}"><i class="fa fa-user post-meta-icon"></i> {{ $user->nickname }}</a></span>
@endforeach
<span><i class="fa fa-calendar-check-o post-meta-icon"></i> {{ $article->created_at->format('F d, Y') }} </span>
</div>
<div class="post-content">
<p>{{{ str_limit($article->text, $limit = 250, $end = '...') }}}</p>
@if ($auth_user && $article->isAuthor($auth_user))
<ul class="list-inline">
<li>
<a href="{{ route('articles.edit',$article->id) }}" class="btn btn-default btn-sm btn-category">{{ __('site.but_edit') }}</a>
</li>
<li>
{{ Form::open(['method' => 'DELETE','route' => ['articles.destroy', $article->id],'style'=>'form-inline']) }}
{{ csrf_field() }}
{{ Form::submit(__('site.but_delete'), ['class' => 'btn btn-default btn-sm btn-back']) }}
{{ Form::close() }}
</li>
</ul>
@endif
</div>
</article>
@endforeach
@else
<article>
<div class="post-content">
<p>{{ __('site.no_articles') }}</p>
</div>
</article>
@endif
</div><!-- main-content -->
<div class="main-content">
@if ($articles)
@foreach ($articles as $article)
<article>
<a href="{{ route('articles.show', $article->id) }}"><h2 class="post-title">{{ $article->title }}</h2></a>
<div class="post-meta">
@foreach ($article->users as $user)
<span><a href="{{ route('authors.articles',$user->id) }}"><i class="fa fa-user post-meta-icon"></i> {{ $user->nickname }}</a></span>
@endforeach
<span><i class="fa fa-calendar-check-o post-meta-icon"></i> {{ $article->created_at->format('F d, Y') }} </span>
</div>
<div class="post-content">
<p>{{{ str_limit($article->text, $limit = 250, $end = '...') }}}</p>
@if ($auth_user && $article->isAuthor($auth_user))
<ul class="list-inline">
<li>
<a href="{{ route('articles.edit',$article->id) }}" class="btn btn-default btn-sm btn-category">{{ __('site.but_edit') }}</a>
</li>
<li>
{{ Form::open(['method' => 'DELETE','route' => ['articles.destroy', $article->id],'style'=>'form-inline']) }}
{{ csrf_field() }}
{{ Form::submit(__('site.but_delete'), ['class' => 'btn btn-default btn-sm btn-back']) }}
{{ Form::close() }}
</li>
</ul>
@endif
</div>
</article>
@endforeach
@else
<article>
<div class="post-content">
<p>{{ __('site.no_articles') }}</p>
</div>
</article>
@endif
</div><!-- main-content -->
Комментарии (5)
composer create-project laravel/laravel --prefer-dist
В результате в каталоге larablog.test будет файл composer.phar и каталог larravel. Из каталога laravel все перемещаем в larablog.test – файл composer.phar и пустой каталог laravel удаляем.
вместо этого лучше composer create-project laravel/laravel ./ --prefer-dist
тогда проект закачается в папку в которой вы находитесь и не нужно будет копировать файлы из папки laravel и потом ее удалять
Принял)
Почему связанная таблица Articles Users создается двумя файлами миграции? Можно ведь одним
articles()
- это метод, а не свойствоЕсли же уже использовать best practises, тогда:
не
$table->integer('user_id')->unsigned()->default(1);
а
$table->unsignedInteger('user_id')->default(1);
не
{{ csrf_field() }}
а
@csrf
Спасибо, поправил.
Зачастую в качестве primary key для связующей таблицы для связи many-many лучше использовать составной ключ (user_id, article_id), без id.