有很多关系不在laravel工作

时间:2016-12-10 12:36:38

标签: laravel

我的购物车型号有:

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

我的产品型号有:

public function cart() {
    return $this->belongsTo('App\Cart');
}

我的数据库看起来像:

购物车表:

enter image description here

产品表:

enter image description here

我的购物车迁移包含:

$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

我的控制器包含:

public function index()
{
   if(Auth::check())       
   {
      $user = Auth::user();
      $cart = Cart::where('user_id',$user->id)->get();
      return view('products.cart')->withCart($cart);
   }
   else {
     return view('products.cart');
   }
}

检查用户是否已登录,然后获取用户ID与当前用户匹配的所有购物车的详细信息。这很有效。

但是当我去product.cart页面时,我尝试:

@foreach($cart->product as $p)
  {{dd($p->name)}}
@endforeach

我收到错误:

Undefined property: Illuminate\Database\Eloquent\Collection::$product (View: D:\wamp64\www\ecommerce\resources\views\products\cart.blade.php)

您能告诉我如何通过这种关系从产品表中获取价值。

谢谢!

修改

尝试了不同的方法后我得到了:

购物车型号:

public function product() {

        return $this->hasMany('App\Product','id','product_id');
    }

购物车控制器:

public function index()
    {
        if(Auth::check())       
        {
            $user = Auth::user();
            $cart = Cart::where('user_id',$user->id)->first();

            return view('products.cart')->withCart($cart);
        }
        else {
            return view('products.cart');
        }
    }

现在我能够获得与id匹配的第一个产品。

有没有办法让所有匹配的产品

4 个答案:

答案 0 :(得分:0)

您使用$...->get()返回集合。请改用first()

$cart = Cart::where('user_id',$user->id)->first();
if($cart) {
    return view('products.cart')->withCart($cart);
} else {
    abort(404);
}

答案 1 :(得分:0)

转到用户的模型:

public function products()
{
    return $this->hasManyThrough('App\Product', 'App\Cart');
}

现在,在您的控制器中,您将获取已登录用户的购物车。并将其传递给视图。 e.g

return view('cart.show', ['cart' => Auth::user()->cart]);

然后你的foreach会像预期的那样工作。

PS:如果您没有使用数据库表的约定命名,则可能必须在hasManyThrough关系上指定id。即模型奇异(产品)到多个表(产品)。

答案 2 :(得分:0)

尝试以下代码。

在您的购物车型号

public function product(){
    return $this->belongsTo('App\Product','id','product_id')
}

在您的控制器

$cart = Cart::where('user_id',$user->id)->first();

答案 3 :(得分:0)

在购物车模型中,您需要指定产品的关系:

public function products(){
  //return $this->hasMany('App\Product'); should be changed to 
    return return $this->belongsToMany('App\Product','carts_products', 'cart_id', 'product_id'); //  see link to tutorial below.
}

通过这种关系,您可以在获得Cart对象时启用延迟加载产品,以便用户在您需要的控制器中实现此目的:

public function index()
{
   if(Auth::check())       
   {
      $user = Auth::user();
      $cart = Cart::with('products')->where('user_id',$user->id)->first();
       //we get cart via first() as we need single instance of cart not an array of carts, 
       //even there's only one cart per user get() will return an array of one item
       // with('products') lazyloads linked products to cart as you get cart instance
      return view('products.cart')->with('cart',$cart);
   }
   else {
     return view('products.cart');
   }
}

稍后在您的视图中,您将能够迭代延迟加载的产品数组,如:

@foreach($cart->products as $p)
 {{dd($p->name)}}
@endforeach

考虑在将来如何访问模型之间创建模型之间的关系,大多数情况下您不需要过度指定对象之间的所有关系,因为只有部分模型可以用来表示模型之间的关系。 ll真的在代码中使用。 希望它会帮助你。

修改

将关系类型更改为belongsToMany,它应该有效,因为您的购物车有很多产品。您仍需要使用first()方法获取一个Cart实例,并根据需要加载相关产品。

重要:

请查看本教程https://scotch.io/tutorials/a-guide-to-using-eloquent-orm-in-laravel,因为您需要更改数据库架构才能实现此目的。目前,您的架构允许您每个购物车只有一个产品。看看这个例子,他们创建野餐到熊表bears_picnics - 在你的情况下,你有产品到购物车表carts_products在你的案例中cart bear {{1} }和picnicsproducts

示例carts_products架构:

   Schema::create('carts_products', function(Blueprint $table)
   {
       $table->increments('id');

       $table->integer('cart_id'); // the id of cart
       $table->integer('product_id'); // the id of product in cart

       $table->timestamps();
   });

从购物车架构中移除product_id字段,因为在这种情况下它无用。如果需要级联删除,请在carts_products表上指定。

快乐编码!谢谢你提出一个很好的问题:)让我们更深入地研究。