hasManyThrough laravel关系

时间:2018-08-29 07:01:08

标签: php laravel eloquent

我在下面有三个表。

+-----------------+   +---------------------+   +-------------+ 
|    products     |   |  product_countries  |   |  countries  |
+-----------------+   +---------------------+   +-------------+ 
|   id            |   |  id                 |   |   id        |
|   name          |   |  product_id         |   |   name      |
|   description   |   |  country_code       |   |   code      |
+-----------------+   |  other columns      |   +-------------+
                      +---------------------+

在Country :: class模型中具有,以获取所有产品。

public function products()
{
    return $this->hasManyThrough(
        'App\Product',
        'App\ProductCountry',
        'product_id', // Foreign key on feeds table...
        'id', // Foreign key on articles table...
        'code', // Local key on users table...
        'country_code' // Local key on feeds table...
    );
}

我想要与一个国家或一个国家有关的产品

$user = \App\Models\Country::find(1);
dd($user->products);

2 个答案:

答案 0 :(得分:1)

您所描述的最佳关系非常适合很多人,通常在Laravel中将其写为双方都是 belongsToMany

class Product extends Model
{
    public function countries()
    {
        return $this->belongsToMany(Country::class);
    }
}

class Country extends Model
{
    public function products()
    {
        return $this->belongsToMany(Product::class);
    }
}

如果您遵循Laravel的命名约定:

  • product_countries重命名为country_product
  • country_product中使用country_id代替country_code

...您应该能够以期望的方式访问这些关系:

$country = \App\Models\Country::find(1);
dd($country->products);

$countries = \App\Models\Country::with('products')->where(...)->get();
foreach ($countries as $country) {
    dd($country->products);
}

如果您不想遵守约定,则可以自定义定义关系的方式。有关更多详细信息,请参见Laravel's documentation


在这种情况下,要使用自定义表名和自定义字段名指定关系,您可以执行以下操作:

// In your Product model
return $this->belongsToMany(Country::class, 'product_countries', 'country_code', 'product_id');

// In your Country model
return $this->belongsToMany(Product::class, 'product_countries', 'product_id', 'country_code');

答案 1 :(得分:1)

Many-to-many是正确的模型关系。如果不是这样,则需要在第二个参数中添加自定义表名称。Eloquent会自动按字母顺序为您创建(例如country_product)。您无需创建ProductCountry模型,因为它只是数据透视表。

您没有发布迁移文件(只是通过猜测),建议使用country_id,但是如果使用country_code / product_id作为外键,则需要添加同样在参数和迁移文件中也是如此(也请检查official documentation

 $table->foreign('product_id')->references('id')->on('products');
 $table->foreign('country_code')->references('code')->on('countries');

尝试这个...

在您的产品型号中

class Product extends Model
{
   public function countries()
   {
      return $this->belongsToMany('App\Country','product_countries','product_id','country_code');
   }
}

在您所在的国家/地区模型中

class Country extends Model
{
   public function products()
   {
      return $this->belongsToMany('App\Product','product_countries','country_code','product_id');
   }
}

在您的控制器中

use App\Country;

$products = Country::find(1)->products()->get(); //finding by id or

$products = Country::where('country_code',$value)->with('products')->get(); //finding by code