在拉瓦雷尔(Lavarel)进行迁移时,我忘了什么呢?展示我想要得到的是我要向用户分配他的订单并订购他订购的产品。因此,我有一个User表,Order表和OrderProduct表。与Order表具有一对多关系的Usera表,与OrderProduct表具有一对多关系的Order表。从关系Order和OrderProduct开始,出现错误:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'order_products_tables.order_table_id' in 'where clause' (SQL: select * from `order_products_tables` where `order_products_tables`.`order_table_id` = 1 and `order_products_tables`.`order_table_id` is not null)
此错误清楚地表明他无法在order_products_tables表中找到order_table_id列,并且我对此并不感到奇怪,因为没有这样的字段,但是有一个order_id字段,并且在迁移中使用哪个字段是关系,我不明白为什么Laravel尝试引用order_products_tables。
迁移顺序:
Schema::create('order_tables', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')
->references('id')
->on('users');
$table->timestamps();
});
迁移OrderProduct:
Schema::create('order_products_tables', function (Blueprint $table) {
$table->increments('id');
$table->integer('order_id')->unsigned();
$table->integer('count')->unsigned();
$table->integer('price')->unsigned();
$table->foreign('order_id')
->references('id')
->on('order_tables');
$table->timestamps();
});
由于迁移导致的结果,order_products_tables表存储了order_tables表中的记录ID,并且关系基于该ID。
模型订单表:
class OrderTable extends Model
{
protected $table = 'order_tables';
public function user()
{
return $this->belongsTo(User::class, 'id');
}
public function products()
{
return $this->hasMany('App\OrderProductTable');
}
}
Model OrderProduct表:
class OrderProductTable extends Model
{
protected $table = 'order_products_tables';
public function order()
{
return $this->belongsTo(OrderTable::class, 'id');
}
}
我不明白为什么要对order_table_id进行引用。我已经按照相同的原则完成了其他关系,例如“用户”和“订单”,并且可以正常工作,突然间我遇到了这种情况。我应该在哪里寻找解决方案,为什么呢?
答案 0 :(得分:1)
此错误来自使用错误的表名,或更准确地说,是未正确定义关系。以下关系定义将解决您的问题:
class OrderTable extends Model
{
protected $table = 'order_tables';
public function products()
{
return $this->hasMany('App\OrderProductTable', 'order_id', 'id');
}
}
class OrderProductTable extends Model
{
protected $table = 'order_products_tables';
public function order()
{
return $this->belongsTo(OrderTable::class, 'order_id', 'id');
}
}
您先前的代码不起作用的原因是Laravel使用默认值,这些默认值基本上是假设,并且要求您的数据库遵循某些命名约定。这是您应遵循的约定列表*:
User
应该有一个名为users
的表。Category
应该有一个名为categories
的表(请参阅英文复数)。AccountManager
应该有一个名为account_managers
的表。Category
和Product
(具有表categories
和products
),并且存在多对多关系(belongsToMany()
)在它们之间,数据透视表的表应该称为order_product
(而不是product_order
,因为o
在字母表中的p
之前)。_id
作为后缀表示的模型之后,将调用外键列:
User
模型上的BlogPost
模型时,Laravel期望将user_id
列作为BlogPost
模型上的外键。 User
模型上引用的主键来自$primaryKey
属性,默认情况下为'id'
。对于您的特定情况,这意味着我们希望使用以下模型,表和列:
User
和列的模型users
,例如在Laravel的默认迁移中。Order
和诸如orders
,id
,user_id
,...之类的列的模型created_at
Product
和诸如products
,id
,name
,...之类的列的模型price
OrderProduct
和诸如order_products
,id
,order_id
,product_id
,...之类的列的模型quantity
理论上,模型OrderProduct
是不必要的。您还应该能够通过在$this->belongsToMany(Product::class)->withPivot('quantity')
模型上定义Order
和在$this->belongsToMany(Order::class)->withPivot('quantity')
模型上定义Product
来构建没有该系统的相同系统(请注意枢轴字段)。就个人而言,我更喜欢用于多对多关系的额外模型。
要了解雄辩的关系,请查看at the documentation。当需要覆盖关系的默认表名或列名时,将提供所有关系类型的示例以及其他参数的附加信息。
*此列表可能缺少重要信息。它是尽力而为。