2016-12-10 206 views
0

我的车模型有:的hasMany关系

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'); 
    } 
} 

它检查是否用户在随后登录其得到所有细节购物车的用户名与当前用户相匹配。这是行得通的。

但是当我去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匹配。

有没有办法让符合

+0

将产品存储在购物车表中并不是一个真正的好方法。我会在会话中存储购物车的内容。 –

+0

'hasMany'的反转是'belongsTo'。你需要使用它。请参阅[文档](https://laravel.com/docs/5.3/eloquent-relationships)。我的猜测是,它应该是_product属于cart_。 – linuxartisan

+0

@linuxartisan更改为'belongsTo'后出现相同的错误 – Phoenix

回答

0

所有的产品可以使用$...->get()回报集合。改为使用first()

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

我收到错误'SQLSTATE [42S22]:未找到列:1054未知列products.cart_id在where子句中(SQL:select * from products where products.cart_id = 1且products.cart_id不为null)' – Phoenix

+0

嗯,你应该多到很多而不是很多。或者保留你的旧代码并用一对一替换hasMany(hasOne)。我将使用多到很多(而不是使用购物车表,直接使用订单表来存储新列'is_paid'或'is_accepted'的订单) – trinvh

0

进入用户的模式:

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

现在,在你的控制,你会获取登录的用户的购物车。并传递给视图。例如

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

然后您的foreach将按预期工作。

PS:如果不使用数据库表的约定命名,则可能必须在hasManyThrough关系上指定ids。即模型单数(产品)复数表(产品)。

0

试试下面的代码。

在你的车型号

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

在控制器

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

我收到错误SQLSTATE [42S22]:未找到列:1054未知列'产品'product'中的'where子句'(SQL:select * from'products' where'products'.'product_id' = 1 limit 1) – Phoenix

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对象,供用户在你的控制器中实现这一点EED:

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 

思考将来,在大多数情况下,你不需要过分指定对象之间的所有关系,因为只有其中一些你会真正使用代码。 希望它能帮助你。

编辑

变化关系类型belongsToMany,它应该工作,因为你的车有很多的产品。您仍然需要使用first()方法获取一个Cart实例,相关产品将根据您的需要进行加载。

重要:

看看这个教程https://scotch.io/tutorials/a-guide-to-using-eloquent-orm-in-laravel,因为你需要改变你的数据库架构来实现这一目标。目前您的模式允许您每个购物车只有一个产品。看看这个例子,他们创造野餐熊表bears_picnics - 在你的情况下,你会有产品到购物车表carts_products在你的情况下通过教程案例cartbearpicnicsproducts

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表中指定它。

快乐编码!感谢您提出一个很好的问题:)使我们深入研究。

+0

我收到错误SQLSTATE [42S22]:找不到列:1054未知列的产品。 cart_id'in'where clause'(SQL:select * from'products' where'products'.'cart_id' in(1)) – Phoenix