laravel提供了强大的模型关联,模型关联可以有效的减少表链接查询复杂操作。
laravel中提供了哪些关联?
一对一 hasOne
一对多 hasMany
一对多反向 belongsTo
多对多 belongsToMany
远层一对一 hasOneThrough
远层一对多 hasManyThrough
多态关联 morphMany
1、一对多演示实例
class article extends Model{
public function articleNav(){
//文章关联模型 一篇文章对应一个栏目
return $this->belongsTo('App/ArticleNav');
}
public function comments(){
//一篇文章对应多篇评论
return $this->hasMany('App/Comments')->orderBy('createtime','desc');
return $this->hasMany('App/Comments');
}
public function addresses()
{
return $this->hasMany(UserAddress::class);
}
}
一个用户拥有多个喜欢的物品
class User extends Model{
public function favoriteProducts()
{
return $this->belongsToMany(Product::class, 'user_favorite_products')
->withTimestamps()
->orderBy('user_favorite_products.created_at', 'desc');
}
public function cartItems()
{
return $this->hasMany(CartItem::class);
}
}withPivot() 可以额外添加获取的参数
withTimestamps() 携带时间戳
一个购物车从属于一个用户
class CartItem extends Model
{
protected $fillable = ['amount'];
public $timestamps = false;
public function user()
{
return $this->belongsTo(User::class);
}
}OrderItem.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OrderItem extends Model
{
protected $fillable = ['amount', 'price', 'rating', 'review', 'reviewed_at'];
protected $dates = ['reviewed_at'];
public $timestamps = false;
public function product()
{
return $this->belongsTo(Product::class);
}
public function productSku()
{
return $this->belongsTo(ProductSku::class);
}
public function order()
{
return $this->belongsTo(Order::class);
}
}order.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Ramsey\Uuid\Uuid;
class Order extends Model
{
const REFUND_STATUS_PENDING = 'pending';
const REFUND_STATUS_APPLIED = 'applied';
const REFUND_STATUS_PROCESSING = 'processing';
const REFUND_STATUS_SUCCESS = 'success';
const REFUND_STATUS_FAILED = 'failed';
const SHIP_STATUS_PENDING = 'pending';
const SHIP_STATUS_DELIVERED = 'delivered';
const SHIP_STATUS_RECEIVED = 'received';
public static $refundStatusMap = [
self::REFUND_STATUS_PENDING => '未退款',
self::REFUND_STATUS_APPLIED => '已申请退款',
self::REFUND_STATUS_PROCESSING => '退款中',
self::REFUND_STATUS_SUCCESS => '退款成功',
self::REFUND_STATUS_FAILED => '退款失败',
];
public static $shipStatusMap = [
self::SHIP_STATUS_PENDING => '未发货',
self::SHIP_STATUS_DELIVERED => '已发货',
self::SHIP_STATUS_RECEIVED => '已收货',
];
protected $fillable = [
'no',
'address',
'total_amount',
'remark',
'paid_at',
'payment_method',
'payment_no',
'refund_status',
'refund_no',
'closed',
'reviewed',
'ship_status',
'ship_data',
'extra',
];
protected $casts = [
'closed' => 'boolean',
'reviewed' => 'boolean',
'address' => 'json',
'ship_data' => 'json',
'extra' => 'json',
];
protected $dates = [
'paid_at',
];
protected static function boot()
{
parent::boot();
// 监听模型创建事件,在写入数据库之前触发
static::creating(function ($model) {
// 如果模型的 no 字段为空
if (!$model->no) {
// 调用 findAvailableNo 生成订单流水号
$model->no = static::findAvailableNo();
// 如果生成失败,则终止创建订单
if (!$model->no) {
return false;
}
}
});
}
public function user()
{
return $this->belongsTo(User::class);
}
public function items()
{
return $this->hasMany(OrderItem::class);
}
public function couponCode()
{
return $this->belongsTo(CouponCode::class);
}
public static function findAvailableNo()
{
// 订单流水号前缀
$prefix = date('YmdHis');
for ($i = 0; $i < 10; $i++) {
// 随机生成 6 位的数字
$no = $prefix.str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
// 判断是否已经存在
if (!static::query()->where('no', $no)->exists()) {
return $no;
}
}
\Log::warning('find order no failed');
return false;
}
}模型处理中处理属性返回
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Product extends Model
{
protected $fillable = [
'title', 'description', 'image', 'on_sale',
'rating', 'sold_count', 'review_count', 'price'
];
protected $casts = [
'on_sale' => 'boolean', // on_sale 是一个布尔类型的字段
];
// 与商品SKU关联
public function skus()
{
return $this->hasMany(ProductSku::class);
}
public function getImageUrlAttribute()
{
// 如果 image 字段本身就已经是完整的 url 就直接返回
if (Str::startsWith($this->attributes['image'], ['http://', 'https://'])) {
return $this->attributes['image'];
}
return \Storage::disk('public')->url($this->attributes['image']);
}
}这里处理了 image 这个字段的属性
分析这条语句做了什么事情:
$items = $event->getOrder()->items()->with(['product'])->get();
1、首先获取到 order 模型
class Order extends Model{
public static $refundStatusMap = [
self::REFUND_STATUS_PENDING => '未退款',
self::REFUND_STATUS_APPLIED => '已申请退款',
self::REFUND_STATUS_PROCESSING => '退款中',
self::REFUND_STATUS_SUCCESS => '退款成功',
self::REFUND_STATUS_FAILED => '退款失败',
];
public static $shipStatusMap = [
self::SHIP_STATUS_PENDING => '未发货',
self::SHIP_STATUS_DELIVERED => '已发货',
self::SHIP_STATUS_RECEIVED => '已收货',
];
protected $fillable = [
'no',
'address',
'total_amount',
'remark',
'paid_at',
'payment_method',
'payment_no',
'refund_status',
'refund_no',
'closed',
'reviewed',
'ship_status',
'ship_data',
'extra',
];
protected $casts = [
'closed' => 'boolean',
'reviewed' => 'boolean',
'address' => 'json',
'ship_data' => 'json',
'extra' => 'json',
];
protected $dates = [
'paid_at',
];
public function items()
{
return $this->hasMany(OrderItem::class);
}
}2、通过with 找到商品
class OrderItem extends Model
{
protected $fillable = ['amount', 'price', 'rating', 'review', 'reviewed_at'];
protected $dates = ['reviewed_at'];
public $timestamps = false;
public function product()
{
return $this->belongsTo(Product::class);
}
public function order()
{
return $this->belongsTo(Order::class);
}
}然后 通过 get 获取关于这个订单所有的数据