Попытка заполнить промежуточную таблицу, используя метод attach (), но получая «Вызов неопределенного метода Illuminate \ Database \ Eloquent \ Relations \ HasMany :: attach ()» - PullRequest
0 голосов
/ 14 мая 2019

У меня есть таблицы с именами users, places и user_place. У users есть столбец с именем id, который содержит идентификатор пользователя, а у мест также есть столбец с именем place_id. Таблица user_place имеет 2 столбца с именами user_id и place_id, и я пытаюсь автоматически заполнить их соответствующими идентификаторами. Я прочитал, что должен использовать функцию attach () после установки отношений, которые, я полагаю, я сделал, но я могу ошибаться. Вот они:

class PlaceController extends Controller
{
    public function likePlace(Request $request){
        $placeId = $request['placeId'];
        $userId = $request['userId'];
        $user = User::where('id', $userId)->first();

        $place = new Place();
        $place->place_id = $placeId;
        $place->save();

        $user->places()->attach($place);
    }
}

Модель пользователя:

class User extends \Eloquent implements Authenticatable
{
    use AuthenticableTrait;

    public function places(){
        return $this->hasMany('App\Place');
    }
}

Режим места:

class Place extends Model
{
    public function user(){
        return $this->belongsToMany('App\User');
    }
}

1 Ответ

1 голос
/ 14 мая 2019

В отношении Многие ко многим вы должны определить оба отношения следующим образом:

User.php

class User extends \Eloquent implements Authenticatable
{
    use AuthenticableTrait;

    public function places()
    {
        return $this->belongsToMany('App\Place', 'user_place', 'user_id', 'place_id');
    }   //                                       ^^^^^^^^^^^^
}

Примечание: Учитывая, что имя вашей промежуточной таблицы не соответствует соглашению об именах , которое мы указали, чтобы Laravel знал, где искать таблицу.

Place.php

Обратите внимание, что вы упомянули, что первичным ключом вашей модели Place является place_id, и это также выходит за рамки Соглашения Laravel , вы должны указать его:

protected $primaryKey = 'place_id'; // <----

class Place extends Model
{
    public function user()
    {
        return $this->belongsToMany('App\User', 'user_place', 'place_id', 'user_id');
    }
}

Так что теперь вваш контроллер:

class PlaceController extends Controller
{
    public function likePlace(Request $request)
    {
        $placeId = $request['placeId'];
        $userId = $request['userId'];

        $user = User::where('id', $userId)->first();

        $place = new Place();
        $place->place_id = $placeId;
        $place->save();

        $user->places()->attach($place);
    }
}

Примечание:

Как примечание, вы можете сохранить пару строк, заменив некоторые предложения их эквивалентами:

    $userId = $request['userId'];
    $user = User::where('id', $userId)->first();

Используя метод find () , он равен:

    $user = User::find($request['userId']);

Затем вы можете создать связанный объект, используя статический метод create модели Eloquent, так:

    $placeId = $request['placeId'];
    $place = new Place();
    $place->place_id = $placeId;
    $place->save();

Это равно:

    $place = Place::create(['place_id' => $request['placeId']]);

Тогда ваш контроллер будет уменьшен доэто:

class PlaceController extends Controller
{
    public function likePlace(Request $request)
    {

        $user = User::find($request['userId']);
        $place = Place::create(['place_id' => $request['placeId']]);

        $user->places()->attach($place);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...