1. 中間テーブルに対して、FormRequest作成
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PlaylistTrackCreate extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'playlist_id' => 'required | unique:playlist_track,playlist_id', 'track_id' => 'required', ]; } /** * カスタムエラーメッセージを設定。 * * @return array */ // "playlist idの値は既に存在しています。" public function messages() { return [ 'playlist_id.unique' => '既にこのプレイリストに追加済みです。', ]; } }
2. Controller側の記述
(FatControllerになっているので、
ビジネスロジックをModel, Serviceに移す。)
class TrackController extends Controller { /** * 選択した曲を選択したプレイリストに所属させ、中間テーブルに保存する。 * * [METHOD - URI] * POST | tracks/addplaylist * * @param * @return Illuminate\Http\Request $request * @throws */ public function addPlaylist(PlaylistTrackCreate $request) // public function addPlaylist(Request $request) { // 現在の選択中の曲を取得 $track = Track::find($request->track_id); // 中間テーブル(playlist_track)にattachメソッドで保存 $track->playlists()->attach( [ 'playlist_id' => $request->playlist_id ], [ 'track_id' => $track->id ] ); $playlist = Playlist::find($request->playlist_id); return redirect()->route('playlists.show', [ 'playlist' => $playlist ]); } }
3. Migration
class CreatePlaylistTrackTable extends Migration { public function up() { Schema::create('playlist_track', function (Blueprint $table) { $table->bigIncrements('id'); $table->bigInteger('track_id')->unsigned(); $table->bigInteger('playlist_id')->unsigned(); $table->timestamps(); $table->foreign('track_id') ->references('id')->on('tracks') ->onDelete('cascade'); $table->foreign('playlist_id') ->references('id')->on('playlists') ->onDelete('cascade'); /** * 中間テーブルならば、複数カラムのユニークでないと * 一つしか登録できないのでdb側に複数ユニークをつける */ $table->unique(['playlist_id', 'track_id']); /** * [重複登録防止の実装自体は成功したので、下記エラーをハンドリングする必要あり。] * * Illuminate\Database\QueryException * * SQLSTATE[23000]: Integrity constraint violation: * 1062 Duplicate entry '2-10' for key 'playlist_track_playlist_id_track_id_unique' * (SQL: insert into `playlist_track` (`created_at`, `playlist_id`, `track_id`, `updated_at`) * values (2020-10-01 19:49:36, 2, 10, 2020-10-01 19:49:36)) * * http://localhost/tracks/addplaylist?playlist_id=2&track_id=10 */ }); } /** * Reverse the migrations. * * @return void */ public function down() { /** * [トラブル解決の参考にした] * https://laracasts.com/discuss/channels/laravel/i-cant-drop-unique-index */ Schema::disableForeignKeyConstraints('playlist_track', function (Blueprint $table) { $table->dropUnique('playlist_track_playlist_id_track_id_unique'); }); Schema::dropIfExists('playlist_track'); } }