Halu_wimps
@Halu_wimps (シガラキ)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Laravel エラー/could not be converted to stringについて助けていただきたいです

解決したいこと

今課題の練習で疑似Twitterを作成しているのですが、
フォロー/フォロー解除/フォロー関係の一覧表示を作ろうとしていたところ↓

発生している問題・エラー

Object of class Illuminate\Database\Eloquent\Relations\BelongsToMany could not be converted to string

このようなエラーが表示されてしまい全く進めない状態でネットで調べてもよくわからないため、
確認したほうがいい箇所や参考サイトなどありましたら教えていただきたいです。

スクリーンショット (1).png

UsersController

app\Http\Controllers\UsersController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Models\User;
use App\Models\Models\Tweet;
use App\Models\Models\Follower;

class UsersController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
     public function index(User $user)
     {
         $all_users = $user->getAllUsers(auth()->user()->id);

         return view('users.index', [
             'all_users'  => $all_users
         ]);
     }

     // フォロー
     public function follow(User $user)
     {
         $follower = auth()->user();
         // フォローしているか
         $is_following = $follower->isFollowing($user->id);
         if(!$is_following) {
             // フォローしていなければフォローする
             $follower->follow($user->id);
             return back();
         }
      }

     // フォロー解除
     public function unfollow(User $user)
     {
         $follower = auth()->user();
         // フォローしているか
         $is_following = $follower->isFollowing($user->id);
         if($is_following) {
             // フォローしていればフォローを解除する
             $follower->unfollow($user->id);
             return back();
         }
     }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

User

app\Models\User.php
<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
  use Notifiable;

  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
      'screen_name',
      'name',
      'profile_image',
      'email',
      'password'
  ];
    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function followers()
   {
       return $this->belongsToMany(self::class, 'followers', 'followed_id', 'following_id');
   }

   public function follows()
   {
       return $this->belongsToMany(self::class, 'followers', 'following_id', 'followed_id');
   }

   public function getAllUsers(Int $user_id)
   {
    return $this->Where('id', '<>', $user_id)->paginate(5);
   }

   // フォローする
   public function follow(Int $user_id)
   {
       return $this->follows()->attach($user_id);
   }

   // フォロー解除する
   public function unfollow(Int $user_id)
   {
       return $this->follows()->detach($user_id);
   }

   // フォローしているか
   public function isFollowing(Int $user_id)
   {
      return $this->follows()->where('followed_id', $this->follows())->where('followed_id', $user_id)->exists();
   }

   // フォローされているか
  public function isFollowed(Int $user_id)
   {
       return (boolean) $this->followers()->where('following_id', $user_id)->first(['id']);
   }

}

View

resources/views/users/index.blade.php
@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                @foreach ($all_users as $user)
                    <div class="card">
                        <div class="card-haeder p-3 w-100 d-flex">
                            <img src="{{ $user->profile_image }}" class="rounded-circle" width="50" height="50">
                            <div class="ml-2 d-flex flex-column">
                                <p class="mb-0">{{ $user->name }}</p>
                                <a href="{{ url('users/' .$user->id) }}" class="text-secondary">{{ $user->screen_name }}</a>
                            </div>
                            @if (auth()->user()->isFollowed($user->id))
                                <div class="px-2">
                                    <span class="px-1 bg-secondary text-light">フォローされています</span>
                                </div>
                            @endif
                            <div class="d-flex justify-content-end flex-grow-1">
                                @if (auth()->user()->isFollowing($user->id))
                                    <form action="{{ route('unfollow', ['id' => $user->id]) }}" method="POST">
                                        {{ csrf_field() }}
                                        {{ method_field('DELETE') }}

                                        <button type="submit" class="btn btn-danger">フォロー解除</button>
                                    </form>
                                @else
                                    <form action="{{ route('follow', ['id' => $user->id]) }}" method="POST">
                                        {{ csrf_field() }}

                                        <button type="submit" class="btn btn-primary">フォローする</button>
                                    </form>
                                @endif
                            </div>
                        </div>
                    </div>
                @endforeach
            </div>
        </div>
        <div class="my-4 d-flex justify-content-center">
            {{ $all_users->links() }}
        </div>
    </div>
@endsection

Routing

routes/web.php
// ログイン状態
Route::group(['middleware' => 'auth'], function() {

    // ユーザ関連
    Route::resource('users', 'UsersController', ['only' => ['index', 'show', 'edit', 'update']]);

    // フォロー/フォロー解除を追加
    Route::post('users/{user}/follow', 'UsersController@follow')->name('follow');
    Route::delete('users/{user}/unfollow', 'UsersController@unfollow')->name('unfollow');

});

自分の知識不足のせいで投げやりな質問の仕方になってしまっていて申し訳ありません。

わかりづらく申し訳ありませんが、ご教授いただけたら幸いです。

実際に作成しているファイルです。↓
https://uploader.cc/s/7thr0vtzf4c548vdgxwzorxc4bqsyo99nitm7mjp0rx7inib8evdq2cbsv0i289a.zip

0

1Answer

app/Models/User.php
   // フォローしているか
   public function isFollowing(Int $user_id)
   {
      return $this->follows()->where('followed_id', $this->follows())->where('followed_id', $user_id)->exists();
   }

この辺怪しいですね。

$this->follows()

0Like

Comments

  1. @Halu_wimps

    Questioner

    ご確認いただきありがとうございます!!
    本当に申し訳ありません、怪しいというのはそこに代入される値の型がということでしょうか。
    それともそのコード自体がということでしょうか・・・
    まだまだ勉強不足で何がなんやらな状態で質問してしまい申し訳ありません・・・
  2. ```
    return $this->follows()->where('followed_id', $this->follows())->where('followed_id', $user_id)->exists();
    ```

    じゃなくて、

    ```
    return $this->follows()->where('followed_id', $user_id)->exists();
    ```

    こう書こうとしたのかなと思いました。

    `->where('followed_id', $this->follows())` の whereメソッドの引数には文字列を渡す必要があります。 `$this->follows()` は `BelongsToMany` の型なので型が違うからエラーになってると思います。

  3. @Halu_wimps

    Questioner

    細かくコードまで記載していただきありがとうございます!!
    最初教えていただいた通り、
    ```
    return $this->follows()->where('followed_id', $user_id)->exists();
    ```
    を書いていたのですがこれでやっていたらまた別のエラーで、
    ```
    Missing required parameter for [Route: follow] [URI: users/{user}/follow] [Missing parameter: user].
    ```
    このようなエラーが出てきてしまっていたため今の状態にしてみたのですが元々書くべきコードが違ったのでしょうか・・・
  4. 別のエラーが出たということは、この表題のエラーについては解決ですね。

    なので、これ以降はまずはググったりして調べてみてください。
    分からなければまた質問するという方がいいです。
    何個エラーが続くか分からないですし、他にも同じ問題で詰まる人もエラーごとに質問が分かれていた方がありがたいと思います。

    と言いたいところですが乗りかかった船なのでオマケで回答します。

    まずはエラーメッセージをよく読んでください。
    「Missing required parameter for ...」はGoogle翻訳すると「必須パラメータが欠落しています。」という意味ですね。

    エラーが出たルーティングの定義はこれですね。

    ```
    Route::post('users/{user}/follow', 'UsersController@follow')->name('follow');
    ```

    Bladeで利用している箇所はここですね

    ```
    <form action="{{ route('follow', ['id' => $user->id]) }}" method="POST">
    ```

    ルーティングの定義では `user` というルートパラメータを指定してるのに Bladeでは `id` というパラメータを渡してます。つまり...そういうことかもですね。

    おそらく一気にコードを書き上げたと思いますが、途中で動作確認を挟みながら進めるのがいいと思います。
  5. @Halu_wimps

    Questioner

    ご確認いただきありがとうございます!!
    他の方の解決のためにもというところまで気が回っていませんでした、ご指摘ありがとうございます!!

    とても分かりやすく指摘をしていただいて有難うございます!!
    無事改善され次に進めました!
    次に進めましたがまたエラーにぶつかったので今度は自力で改善できるように調べて対策してみます!

    動作確認の重要さを痛感しました・・・
    色々なことを教えていただき本当にありがとうございます!!

Your answer might help someone💌