我是Laravel的新手,并且在关系如何运作方面遇到了一些困难。我正在构建一个简单的电子商务应用程序,其中每个用户都有一些订单,订单有一个或多个子订单,每个子订单只链接到一个项目(请不要评论我的计划呢;现在我只需要找出Eloquent并将在稍后进行重构:))。
以下是我的模特:
class Order extends Model
{
//timestamp
protected $created_at;
public function sub_orders() {
return $this->hasMany('App\SubOrder');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class SubOrder extends Model
{
protected $fillable = array('delivery_date', 'quantity', 'total_price', 'delivery_status');
public function item() {
return $this->hasOne('App\Item');
}
public function order() {
return $this->belongsTo('App\Order');
}
}
class Item extends Model
{
//note - slug is kind of categorization and is common to many items
protected $fillable = array('sku', 'name', 'slug', 'unit_price');
}
以下是迁移:
class CreateOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at');
//foreign keys
$table->unsignedInteger('user_id')->after('id');
$table->foreign('user_id')->references('id')->on('users') ->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('orders');
}
}
class CreateSubOrdersTable extends Migration
{
public function up()
{
Schema::create('sub_orders', function (Blueprint $table) {
$table->increments('id');
$table->date('delivery_date');
$table->decimal('quantity', 5, 2);
$table->decimal('total_price', 7, 2);
$table->enum('delivery_status', ['pending_from_farmer', 'ready_for_customer', 'out_for_delivery', 'delivered']);
//foreign keys
$table->unsignedInteger('order_id')->after('id');
$table->foreign('order_id')->references('id')->on('orders') ->onDelete('cascade');
$table->unsignedInteger('item_id')->after('order_id');
$table->foreign('item_id')->references('id')->on('items') ->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('sub_orders');
}
}
class CreateItemsTable extends Migration
{
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->increments('id');
$table->string('sku')->unique();
$table->string('name');
$table->string('slug');
$table->decimal('unit_price', 5, 2);
});
}
public function down()
{
Schema::dropIfExists('items');
}
}
有问题的表达式是我在App\Order::all()[0]->sub_orders[0]->item
中编写web.php
并收到以下错误的原因:
SQLSTATE[42703]: Undefined column: 7 ERROR: column items.sub_order_id does not exist
LINE 1: select * from "items" where "items"."sub_order_id" = $1 and ...
^ (SQL: select * from "items" where "items"."sub_order_id" = 1 and "items"."sub_order_id" is not null limit 1)
我不明白为什么它在sub_order_id
表中寻找items
。什么是正确的方法呢?
答案 0 :(得分:1)
总体而言:使用hasOne
或belongsTo
定义一对一关系将影响Laravel找到外键的目标表。 hasOne
假设目标表格中有my_model_id
。belongsTo
假设我的表格中有target_model_id
。
class SubOrder extends Model
{
public function item() {
return $this->hasOne('App\Item', 'id', 'item_id');
}
}
或
class SubOrder extends Model
{
public function item() {
return $this-> belongsTo('App\Item');
}
}
class User extends Model
{
/**
* Get the phone record associated with the user.
*/
public function phone()
{
return $this->hasOne('App\Phone');
}
}
Eloquent根据模型名称确定关系的外键。在上述情况下,会自动假设电话型号具有 user_id外键。如果要覆盖此约定,可以将第二个参数传递给hasOne方法:
$this->hasOne('App\Phone', 'foreign_key', 'local_key');
或定义关系的反转
class Phone extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
在上面的示例中,Eloquent会尝试将 user_id从手机模型与用户模型上的 ID匹配。
答案 1 :(得分:1)
您的SubOrder
项与OneToOne
类型的关系(hasOne
是双向的)与项目的关系。
因此Eloquent
期望sub_order_id
表中包含items
。
因此,解决方案是在belongsTo
模型中定义此关系的倒数(Item
)