🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1371閲覧

【Laravel】Form::modelを使ったアクションで、引数に値を入れているつもりなのに渡せていないとエラーが出る

hazuki_

総合スコア2

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/01/23 01:37

前提・実現したいこと

LaravelとMySQLを使用して本のタイトル一覧を表示するプログラムを作成し、ログイン機能をつけ、現在はお気に入り機能をつけているところです。

お気に入り追加やお気に入り一覧表示の機能はなんとかつけられたのですが、お気に入り解除の機能でどうしてもエラーが出てしまいます。

発生している問題・エラーメッセージ

attach()やdetach()を使用してお気に入りの追加と解除の機能をつけようとしていたのですが、解除の方だけどうしても上手くできずエラーが出てしまいます。
引数がないというエラーだと思うのですが、なぜ渡せていないのかがわかりません。
indexFavorites.blade.php内のForm::model内の記述で$book->idを渡せていると思っていたのですが認識違いでしょうか?

また解除用のフォームのactionが指定したURLと異なっているのですが関係はありますでしょうか?
action="http://〜〜8000/favorites?1"などになっていて、
最後に?1となっている数字の部分が$book->idと同じ値になっているのですが、コントローラでは
return redirect('/favorites');
で元のページに戻るようにしています。
加えて、このリダイレクトの中を('/')や('/books')に変更しても反映されず/favorites?1のままでした。

質問文がわかりにくくすみません、お答えいただけると幸いです。
よろしくお願いいたします。

// エラーメッセージ Type error: Too few arguments to function App\Http\Controllers\FavoritesController::unfavorite(), 0 passed and exactly 1 expected

該当のソースコード

php

1//web.php 2Route::get('/', function (){ //トップページ表示 3 return view('welcome'); 4}); 5 6Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); 7// login.blade.phpを返すというファンクションが既に設定されている 8Route::post('login', 'Auth\LoginController@login')->name('login.post'); 9Route::get('logout', 'Auth\LoginController@logout')->name('logout.get'); 10 11Route::get('signup', 'Auth\RegisterController@showRegistrationForm')->name('signup.get'); //新規ユーザー登録ページ表示 12Route::post('/', 'Auth\RegisterController@register')->name('signup.post'); //新規ユーザー登録アクション 13 14/** ログインしないと入れない処理 */ 15Route::group(['middleware' => ['auth']], function(){ 16 Route::get('books/create', 'BooksController@create')->name('books.create'); //新規作成ページ表示 17 Route::get('books/{id}', 'BooksController@show')->name('books.show'); //詳細ページ表示 18 Route::post('books', 'BooksController@store')->name('books.store'); //登録アクション →登録後トップページに飛ばす 19 Route::put('books/{id}', 'BooksController@update')->name('books.update'); //更新アクション →更新後詳細ページに飛ばす 20 Route::delete('books/{id}', 'BooksController@destroy')->name('books.destroy'); //削除アクション →削除後詳細ページに飛ばす 21 22 Route::get('books', 'BooksController@index')->name('books.index'); //一覧ページ表示 23 Route::get('books/{id}/edit', 'BooksController@edit')->name('books.edit'); //更新ページ表示 24 25 Route::get('favorites', 'FavoritesController@indexFavorites')->name('books.indexFavorites'); 26 Route::patch('books/{id}', 'FavoritesController@favorite')->name('books.favorite'); 27 Route::patch('favorites', 'FavoritesController@unfavorite')->name('books.unfavorite'); 28});

php

1//FavoritesController.php 2 3<?php 4namespace App\Http\Controllers; 5 6use Illuminate\Http\Request; 7use Illuminate\Support\Facades\Auth; 8 9class FavoritesController extends Controller 10{ 11 // 12 public function indexFavorites() { 13 $user = Auth::user(); 14 $books = $user->favorites()->paginate(5); 15 return view('books.indexFavorites', ['user' => $user, 'books' => $books,]); 16 } 17 18 public function is_favorite($book_id) { //お気に入りの中に入っているかのチェック 19 $user = Auth::user(); 20 return $user->favorites()->where('book_id', $book_id)->exists(); 21 } 22 23 public function favorite($book_id) { //単数形 24 $user = Auth::user(); 25 $is_favorite = $this->is_favorite($book_id); 26 $exist = $user->$is_favorite; //引数に入っている本がお気に入りに入っているかどうか 27 if ($exist){ 28 return false; //すでにお気に入りに入ってたらfalseを返す 29 } else { 30 $user->favorites()->attach($book_id); //お気に入りに入ってなかったらお気に入りに入れて、trueを返す 31 return redirect('/favorites'); 32 } 33 } 34 35 public function unfavorite($book_id) { //単数形 36 $user = Auth::user(); 37 $is_favorite = $this->is_favorite($book_id); 38 $exist = $user->$is_favorite; //引数に入っている本がお気に入りに入っているかどうか 39 if($exist){ 40 $user->favorites()->detach($book_id); //お気に入りに入ってたらお気に入りから消して、trueを返す 41 return redirect('/favorites'); 42 } else { 43 return false; //お気に入りに入ってなかったらfalseを返す 44 } 45 } 46}

php

1//indexFavorites.blade.php 2@extends('layouts.app') 3@section('content') 4 5<h1>{{ $user->name }}さんのお気に入り一覧</h1> 6@if(count($books) > 0) 7 <ul class="book-list"> 8 @foreach ($books as $book) 9 <li> 10 {!! link_to_route('books.show', $book->id, ['id' => $book->id]) !!} 11 <p>{{ $book->book_title }}</p> 12 {!! Form::model($book, ['route' => ['books.unfavorite', $book->id], 'method' => 'patch']) !!} 13 {!! Form::submit('お気に入り解除') !!} 14 {!! Form::close() !!} 15 </li> 16 @endforeach 17 </ul> 18 {!! $books->render() !!} 19@else 20 <p>お気に入りはまだありません</p> 21@endif 22 23<a href="{{ url('/') }}">戻る</a> 24 25@endsection

php

1//show.blade.php 2@extends('layouts/app') 3@section('content') 4 5 <h1>id: {{ $book->id }} の詳細ページ</h1> 6 title: {{ $book->book_title }}<br> 7 {!! link_to_route('books.edit', '編集', ['id' => $book->id,]) !!} 8 {!! Form::model($book, ['route' => ['books.favorite', $book->id], 'method' => 'patch']) !!} 9 {!! Form::submit('お気に入り登録') !!} 10 {!! Form::close() !!} 11 {!! Form::model($book, ['route' => ['books.destroy', $book->id], 'method' => 'delete']) !!} 12 {!! Form::submit('削除') !!} 13 {!! Form::close() !!} 14 15 {!! link_to_route('books.index', 'トップに戻る') !!} 16 17@endsection

php

1//BooksController.php 2<?php 3 4namespace App\Http\Controllers; 5 6use Illuminate\Http\Request; 7use App\Book; 8 9class BooksController extends Controller 10{ 11 // トップページ (一覧ページ) 12 public function index() { 13 $books = Book::paginate(5); 14 return view('books.index', ['books' => $books,]); 15 } 16 17 // 新規登録ページ表示 18 public function create() { 19 $book = new Book; 20 return view('books.create', ['book' => $book,]); 21 } 22 23 // 新規登録アクション 24 public function store(Request $request) { 25 $this->validate($request, ['book_title' => 'required|max:191',]); 26 27 $book = new Book; 28 $book->book_title = $request->book_title; 29 $book->save(); 30 return redirect('/books'); 31 } 32 33 // 詳細ページ 34 public function show($id) { 35 $book = Book::find($id); 36 return view('books.show', ['book' => $book,]); 37 } 38 39 // 編集ページ表示 40 public function edit($id) { 41 $book = Book::find($id); 42 return view('books.edit', ['book' => $book,]); 43 } 44 45 // データ更新アクション 46 public function update(Request $request, $id) { 47 $book = Book::find($id); 48 $book->book_title = $request->book_title; 49 $book->save(); 50 return redirect('/books'); 51 } 52 53 // データ削除アクション 54 public function destroy($id) { 55 $book = Book::find($id); 56 $book->delete(); 57 58 return redirect('/books'); 59 } 60}

php

1//Book.php 2namespace App; 3 4use Illuminate\Database\Eloquent\Model; 5 6class Book extends Model 7{ 8 // 9 protected $fillable = ['book_title', 'user_id']; 10 11 public function user() { 12 return $this->belongsTo(User::class); 13 } 14} 15

php

1// User.php 2namespace App; 3 4use Illuminate\Notifications\Notifiable; 5use Illuminate\Foundation\Auth\User as Authenticatable; 6 7class User extends Authenticatable 8{ 9 use Notifiable; 10 11 /** 12 * The attributes that are mass assignable. 13 * 14 * @var array 15 */ 16 protected $fillable = [ 17 'name', 'email', 'password', 18 ]; 19 20 /** 21 * The attributes that should be hidden for arrays. 22 * 23 * @var array 24 */ 25 protected $hidden = [ 26 'password', 'remember_token', 27 ]; 28 29 public function books() { 30 return $this->hasMany(Book::class); 31 } 32 33 public function favorites() { //複数形 34 return $this->belongsToMany(Book::class); 35 } 36 37

試したこと

・お気に入り解除用のフォームをループから出す(show.blade.phpで記述してみる)
⇒変化なし
・unfavorite()のメソッド名をremoveFavorite()に変えてみる
⇒変化なし
・お気に入り解除フォームの['route' => ['books.unfavorite', $book->id]の箇所を
actionを使った書き方に変えてみた(実際にどう記述してみたか忘れてしまいました…)
⇒変化なし
・お気に入り解除時のメソッドをpatchからpostにしてみた
⇒変化なし
・Form部分の記述が間違っていないか確認
⇒間違ってはいない気はしますが結果エラーなので自信はありません

補足情報(FW/ツールのバージョンなど)

Mac OS
VScode
Laravel Framework 5.5.50
MySQL 5.7.32
Laravel Collective 5.4.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

php

1Route::patch('favorites', 'FavoritesController@unfavorite')->name('books.unfavorite');

ここでパラメータ定義していないからでは?

投稿2021/01/23 02:27

phper.k

総合スコア3923

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hazuki_

2021/01/23 06:11

ご回答ありがとうございます。 すみません、もう少し詳しく教えていただいても良いでしょうか? パラメータ定義とは https://readouble.com/laravel/5.7/ja/routing.html のルートパラメーターのことでしょうか?
phper.k

2021/01/23 06:19

unfavorite($book_id) と定義してんなら、 Route::patch('favorites/{book_id}', 'FavoritesController@unfavorite')->name('books.unfavorite'); こうしなきゃいかんでしょ
hazuki_

2021/01/23 22:58

お返事が遅くなりすみません!ありがとうございます、試してみます!
hazuki_

2021/01/23 23:04

あとすみません、 >>unfavorite($book_id) と定義してんなら、 Route::patch('favorites/{book_id}', 'FavoritesController@unfavorite')->name('books.unfavorite'); こうしなきゃいかんでしょ ⇒の理由が少しわかっていないです、すみません。 引数の部分をルーティングの際にパスに使わないといけない、という感じでしょうか?
phper.k

2021/01/24 00:47 編集

理由も何も、そういうルールで書くのがLaravel ですから。 ネットの情報つぎはぎでやるんじゃなくて、入門書でも読んで体型的に覚えたほうがいいんじゃないですか?
hazuki_

2021/01/24 03:49

どういうルールなのかがわからないので探してみます! 指摘通りやってみたらエラー内容が変わったので他の修正します。ありがとうございました!
hazuki_

2021/01/25 05:34

※メモです ルーティングの中の{ }の意味をちゃんとわかっていませんでしたが https://readouble.com/laravel/5.5/ja/routing.html のルートパラメーターの箇所を見てわかりました。 unfavorite($book_id)の引数部分は Route::patch('favorites/{book_id}', 'FavoritesController@unfavorite')->name('books.unfavorite'); のようにしてルート(生成されたURL?)から取り出せるようにしないといけなかったみたいです。 book_idの箇所は勝手に値が入って、URL生成に使われるだけという勘違いをしていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問