php - 尝试使用 attach() 填充中间表,但得到“调用未定义的方法 Illuminate\Database\Eloquent\Relations\HasMany::attach()”
问题描述
我有名为users
,places
和的表user_place
。users
有一个名为的列id
,其中包含用户的 id,places 也有一个名为的列place_id
。该user_place
表有 2 列称为user_id
,place_id
我正在尝试使用相应的 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');
}
}
解决方案
在多对多关系中,您应该定义两种关系,如下所示:
用户.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']);
然后,您可以使用 Eloquent 模型的静态方法创建相关对象,create
这样:
$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);
}
}
推荐阅读
- java - 如何读取excel文件并将其转换为java抽象类?
- apache-storm - 在风暴拓扑和工作人员重新启动中获取与 Netty 客户端相关的错误
- string - 使用 xlsxwriter:带字符串的工作表 data_validation 将逗号转换为 \n
- java - 无法在 getView() 中更改线性布局高度
- function - 使用 VUE.js 在滚动上查找 div
- sql - SQL BigQuery:计算每个时间段的值
- spring - @Transactional 方面有什么样的切入点?之前,之后还是周围?
- python - PostgreSql、QSqlDatabase:无法打开数据库
- php - 无法将 PHP 连接到 XAMPP 数据库以发送数据
- transactions - Hyperledger-composer 访问控制规则和事务