我的购物车型号有:
public function product() {
return $this->hasMany('App\Product');
}
我的产品型号有:
public function cart() {
return $this->belongsTo('App\Cart');
}
我的数据库看起来像:
购物车表:
产品表:
我的购物车迁移包含:
$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匹配的第一个产品。
有没有办法让所有匹配的产品
答案 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} }和picnics
是products
。
示例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
表上指定。
快乐编码!谢谢你提出一个很好的问题:)让我们更深入地研究。