Laravel Scout/Algolia: 模型关系没有通过索引
Laravel Scout/Algolia: Model relationships not pulling through to index
我有 3 个模型——Products、Users 和 UserProducts。 UserProduct 是特定产品的实例,具有用户对该项目的特定价格、产品代码等。因此,一个产品可以有许多用户产品,并且通过这些用户产品,可以有许多用户。这些关系在产品模型中定义:
public function userProducts() {
return $this->hasMany(UserProduct::class);
}
public function users() {
return $this->belongsToMany(User::class, 'user_products');
}
我知道这些关系正在发挥作用,因为在 Artisan Tinker 中,我将其中任何一个调用为 属性。
在我的 Algolia products 索引中,我希望结果包含有关用于过滤的相关用户和 UserProducts 的信息。因此,我按照 Scout Extended 和 Algolia 文档中的建议加载这些关系:
public function toSearchableArray() {
$this->users;
$this->userProducts;
$array = $this->toArray();
// Apply Scout Extended default transformations:
$array = $this->transform($array);
return $array;
}
一切都在顺利进行,但出于某种原因,“用户”和“user_products”空无一人。
具有“用户”和 'product' 关系的 UserProducts 在将这些关系拉入我的 user_products 索引:
据此,我只能得出结论,问题一定在于我如何设置填充数据库的工厂文件。对于 UserProducts,我使用了一个简单的工厂:
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\UserProduct;
use Faker\Generator as Faker;
$factory->define(UserProduct::class, function (Faker $faker) {
return [
'code' => 'EAN' . $faker->ean8,
'price' => $faker->randomFloat(2, 5, 1000),
'product_id' => App\Product::all()->random()->id,
'user_id' => App\User::where('type', 'supplier')->inRandomOrder()->first()->id
];
});
... 而在用户工厂中发生的事情有点复杂:
$factory->define(User::class, function (Faker $faker) {
return [
'display_name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'phone' => $faker->phoneNumber,
'type' => array_rand(['supplier', 'buyer']),
'profile_completed' => true,
'email_verified_at' => now(),
'password' => 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
});
$factory->afterCreating(User::class, function ($user, $faker) {
$user->assignRole($user->type);
if($user->type==='supplier') {
// create five products for them
$products = factory(App\Product::class, 5)->create();
$products->each(function($product) use ($user) {
$user_product = factory(App\UserProduct::class)->create([
'product_id' => $product->id,
'user_id' => $user->id
]);
})->each(function($product){
$product->setUserProductCount();
$product->update();
});
}
});
在 afterCreating 回调中所做的所有更改已成功执行。但是,无论对这段代码进行多少改动,添加 $product->searchable() 等似乎都可以将必要的数据带到我的产品索引中。任何有用的建议将不胜感激。
可能是您忘记在产品型号上使用 Laravel 的 touch
功能。参见 https://www.algolia.com/doc/framework-integration/laravel/indexing/configure-searchable-data/?language=php#updating-relations-when-parentchild-change
如果这能解决您的问题,请告诉我
我有 3 个模型——Products、Users 和 UserProducts。 UserProduct 是特定产品的实例,具有用户对该项目的特定价格、产品代码等。因此,一个产品可以有许多用户产品,并且通过这些用户产品,可以有许多用户。这些关系在产品模型中定义:
public function userProducts() {
return $this->hasMany(UserProduct::class);
}
public function users() {
return $this->belongsToMany(User::class, 'user_products');
}
我知道这些关系正在发挥作用,因为在 Artisan Tinker 中,我将其中任何一个调用为 属性。
在我的 Algolia products 索引中,我希望结果包含有关用于过滤的相关用户和 UserProducts 的信息。因此,我按照 Scout Extended 和 Algolia 文档中的建议加载这些关系:
public function toSearchableArray() {
$this->users;
$this->userProducts;
$array = $this->toArray();
// Apply Scout Extended default transformations:
$array = $this->transform($array);
return $array;
}
一切都在顺利进行,但出于某种原因,“用户”和“user_products”空无一人。
具有“用户”和 'product' 关系的 UserProducts 在将这些关系拉入我的 user_products 索引:
据此,我只能得出结论,问题一定在于我如何设置填充数据库的工厂文件。对于 UserProducts,我使用了一个简单的工厂:
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\UserProduct;
use Faker\Generator as Faker;
$factory->define(UserProduct::class, function (Faker $faker) {
return [
'code' => 'EAN' . $faker->ean8,
'price' => $faker->randomFloat(2, 5, 1000),
'product_id' => App\Product::all()->random()->id,
'user_id' => App\User::where('type', 'supplier')->inRandomOrder()->first()->id
];
});
... 而在用户工厂中发生的事情有点复杂:
$factory->define(User::class, function (Faker $faker) {
return [
'display_name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'phone' => $faker->phoneNumber,
'type' => array_rand(['supplier', 'buyer']),
'profile_completed' => true,
'email_verified_at' => now(),
'password' => 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
});
$factory->afterCreating(User::class, function ($user, $faker) {
$user->assignRole($user->type);
if($user->type==='supplier') {
// create five products for them
$products = factory(App\Product::class, 5)->create();
$products->each(function($product) use ($user) {
$user_product = factory(App\UserProduct::class)->create([
'product_id' => $product->id,
'user_id' => $user->id
]);
})->each(function($product){
$product->setUserProductCount();
$product->update();
});
}
});
在 afterCreating 回调中所做的所有更改已成功执行。但是,无论对这段代码进行多少改动,添加 $product->searchable() 等似乎都可以将必要的数据带到我的产品索引中。任何有用的建议将不胜感激。
可能是您忘记在产品型号上使用 Laravel 的 touch
功能。参见 https://www.algolia.com/doc/framework-integration/laravel/indexing/configure-searchable-data/?language=php#updating-relations-when-parentchild-change
如果这能解决您的问题,请告诉我