参数 #3 ($constraints) 必须是 Closure 类型,数组给定
Argument #3 ($constraints) must be of type Closure, array given
我正在尝试呈现来自用户的所有广告。用户在他的 table 中保存了纬度和经度,所以我想做的是过滤一些地方,这些地方将绘制该搜索区域中那些用户的 ads/posts(我正在使用 google 地图 api),但我不断收到此消息,我无法使用 Vue 呈现页面。
lluminate\Database\Eloquent\Builder::eagerLoadRelation(): Argument #3 ($constraints) must be of type Closure, array given,
我有广告和用户。一个用户包含一个地方的经纬度,这是我的模型(我把它缩短了):
class User extends Authenticatable {
protected $fillable = [ 'name', 'email', 'email_verified_at', 'password', 'address', 'lat', 'lng' 'published_ad_id' ];
public function ads(){
return $this->hasMany("App\Models\Ad", "published_ad_id");
}
}
这是我的广告模型:
class Ad extends Model
{
use HasFactory;
protected $table = 'ads';
protected $primaryKey = 'id';
protected $fillable = ['user_id','title', 'description', 'image', 'music_genre'];
// protected $guarded = ['created_at', 'updated_at', 'availabilities_id'];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function availability()
{
return $this->hasOne(Availability::class , 'availabilities_id');
}
}
这将是我的控制器:
class AnuncioController extends Controller
{
public function index(Request $request)
{
// $anuncios = Ad::query();
$userLocationLat = $request->input('lat');
$userLocationLng = $request->input('lng');
$distance = $request->input('distance');
$nearestUsers = [];
foreach (User::all() as $users){
$distanceBetweenLocations = $this->getDistance($users->lat, $users->lng, $userLocationLat, $userLocationLng);
if ($distanceBetweenLocations <= $distance ){
$nearestUsers[] = $users;
}
// elseif ($userLocationLat == null){
// $nearestUsers[] = $users;
// }
}
$anuncios = Ad::with(['user'=>$nearestUsers])->latest()->paginate(5)->withQueryString();
return Inertia::render('Anuncio/Index', compact('anuncios')
);
}
private function getDistance($point1_lat, $point1_long, $point2_lat, $point2_long, $unit = 'km', $decimals = 2) {
// Calculate the distance in degrees
$degrees = rad2deg(acos((sin(deg2rad($point1_lat))*sin(deg2rad($point2_lat))) + (cos(deg2rad($point1_lat))*cos(deg2rad($point2_lat))*cos(deg2rad($point1_long-$point2_long)))));
// Convert the distance in degrees to the chosen unit (kilometres, miles or nautical miles)
switch($unit) {
case 'km':
$distance = $degrees * 111.13384; // 1 degree = 111.13384 km, based on the average diameter of the Earth (12,735 km)
break;
case 'mi':
$distance = $degrees * 69.05482; // 1 degree = 69.05482 miles, based on the average diameter of the Earth (7,913.1 miles)
break;
case 'nmi':
$distance = $degrees * 59.97662; // 1 degree = 59.97662 nautic miles, based on the average diameter of the Earth (6,876.3 nautical miles)
}
return round($distance, $decimals);
}
}
如您所见,我正在尝试传递用户数组,以便我可以在前面的部分使用它,但没有用。
在前面我有这个vue.js:
<template>
<AppLayout>
<h1>HOLA</h1>
<div v-for="anuncio in anuncios" :key="anuncio.id" class="max-w-sm rounded overflow-hidden shadow-lg">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">{{ anuncio.title }}</div>
<p class="text-gray-700 text-base">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
</p>
<p>
{{anuncio.description}}
</p>
<p>
{{ anuncio.user.name}}
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#photography</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#travel</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#winter</span>
</div>
</div>
</AppLayout>
</template>
<script>
import AppLayout from "../../Layouts/AppLayout";
export default {
name: "index",
// props: ['restaurants'],
props: {
anuncios: Object
},
components: {AppLayout}
}
</script>
<style scoped>
</style>
我认为问题出在控制器以及我如何将数据传递给 Ads,但我找不到哪里做错了或如何获取该数组。
你应该使用闭包作为值并在里面过滤。
$anuncios = Ad
::with([
'user' => function ($query) use ($nearestUsers) {
$query->whereIn('id', $nearestUsers)
}
])
->latest()
->paginate(5)
->withQueryString();
尝试将所有用户 ID 收集到 $nearestUsers
数组,并使用该数组过滤广告。
像这样,
foreach (User::all() as $users){
$distanceBetweenLocations = $this->getDistance($users->lat, $users->lng, $userLocationLat, $userLocationLng);
if ($distanceBetweenLocations <= $distance ){
$nearestUsers[] = $users->id;
}
}
$anuncios = Ad::with(['user'])->whereIn('user_id', $nearestUsers)->latest()->paginate(5)->withQueryString();
我正在尝试呈现来自用户的所有广告。用户在他的 table 中保存了纬度和经度,所以我想做的是过滤一些地方,这些地方将绘制该搜索区域中那些用户的 ads/posts(我正在使用 google 地图 api),但我不断收到此消息,我无法使用 Vue 呈现页面。
lluminate\Database\Eloquent\Builder::eagerLoadRelation(): Argument #3 ($constraints) must be of type Closure, array given,
我有广告和用户。一个用户包含一个地方的经纬度,这是我的模型(我把它缩短了):
class User extends Authenticatable {
protected $fillable = [ 'name', 'email', 'email_verified_at', 'password', 'address', 'lat', 'lng' 'published_ad_id' ];
public function ads(){
return $this->hasMany("App\Models\Ad", "published_ad_id");
}
}
这是我的广告模型:
class Ad extends Model
{
use HasFactory;
protected $table = 'ads';
protected $primaryKey = 'id';
protected $fillable = ['user_id','title', 'description', 'image', 'music_genre'];
// protected $guarded = ['created_at', 'updated_at', 'availabilities_id'];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function availability()
{
return $this->hasOne(Availability::class , 'availabilities_id');
}
}
这将是我的控制器:
class AnuncioController extends Controller
{
public function index(Request $request)
{
// $anuncios = Ad::query();
$userLocationLat = $request->input('lat');
$userLocationLng = $request->input('lng');
$distance = $request->input('distance');
$nearestUsers = [];
foreach (User::all() as $users){
$distanceBetweenLocations = $this->getDistance($users->lat, $users->lng, $userLocationLat, $userLocationLng);
if ($distanceBetweenLocations <= $distance ){
$nearestUsers[] = $users;
}
// elseif ($userLocationLat == null){
// $nearestUsers[] = $users;
// }
}
$anuncios = Ad::with(['user'=>$nearestUsers])->latest()->paginate(5)->withQueryString();
return Inertia::render('Anuncio/Index', compact('anuncios')
);
}
private function getDistance($point1_lat, $point1_long, $point2_lat, $point2_long, $unit = 'km', $decimals = 2) {
// Calculate the distance in degrees
$degrees = rad2deg(acos((sin(deg2rad($point1_lat))*sin(deg2rad($point2_lat))) + (cos(deg2rad($point1_lat))*cos(deg2rad($point2_lat))*cos(deg2rad($point1_long-$point2_long)))));
// Convert the distance in degrees to the chosen unit (kilometres, miles or nautical miles)
switch($unit) {
case 'km':
$distance = $degrees * 111.13384; // 1 degree = 111.13384 km, based on the average diameter of the Earth (12,735 km)
break;
case 'mi':
$distance = $degrees * 69.05482; // 1 degree = 69.05482 miles, based on the average diameter of the Earth (7,913.1 miles)
break;
case 'nmi':
$distance = $degrees * 59.97662; // 1 degree = 59.97662 nautic miles, based on the average diameter of the Earth (6,876.3 nautical miles)
}
return round($distance, $decimals);
}
}
如您所见,我正在尝试传递用户数组,以便我可以在前面的部分使用它,但没有用。
在前面我有这个vue.js:
<template>
<AppLayout>
<h1>HOLA</h1>
<div v-for="anuncio in anuncios" :key="anuncio.id" class="max-w-sm rounded overflow-hidden shadow-lg">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">{{ anuncio.title }}</div>
<p class="text-gray-700 text-base">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
</p>
<p>
{{anuncio.description}}
</p>
<p>
{{ anuncio.user.name}}
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#photography</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#travel</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#winter</span>
</div>
</div>
</AppLayout>
</template>
<script>
import AppLayout from "../../Layouts/AppLayout";
export default {
name: "index",
// props: ['restaurants'],
props: {
anuncios: Object
},
components: {AppLayout}
}
</script>
<style scoped>
</style>
我认为问题出在控制器以及我如何将数据传递给 Ads,但我找不到哪里做错了或如何获取该数组。
你应该使用闭包作为值并在里面过滤。
$anuncios = Ad
::with([
'user' => function ($query) use ($nearestUsers) {
$query->whereIn('id', $nearestUsers)
}
])
->latest()
->paginate(5)
->withQueryString();
尝试将所有用户 ID 收集到 $nearestUsers
数组,并使用该数组过滤广告。
像这样,
foreach (User::all() as $users){
$distanceBetweenLocations = $this->getDistance($users->lat, $users->lng, $userLocationLat, $userLocationLng);
if ($distanceBetweenLocations <= $distance ){
$nearestUsers[] = $users->id;
}
}
$anuncios = Ad::with(['user'])->whereIn('user_id', $nearestUsers)->latest()->paginate(5)->withQueryString();