我一直在玩 laravel 并遇到了一个奇怪的边缘案例,我无法弄清楚
我有以下表结构:
CREATE TABLE `community_address` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`address_id` int(10) unsigned NOT NULL,
`community_id` int(10) unsigned NOT NULL,
`is_billing` tinyint(1) NOT NULL DEFAULT '1',
`is_service` tinyint(1) NOT NULL DEFAULT '1',
`is_mailing` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
)
CREATE TABLE `communities` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
)
CREATE TABLE `addresses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`address_1` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Street address',
`address_2` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Street adddress 2 (Company name, Suite, etc)',
`city` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'City',
`state` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'State / Province',
`zip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Zip / Postal Code',
`country_id` int(10) unsigned NOT NULL COMMENT 'Country ID',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
)
我用以下 Laravel 模型代表了一个社区
class Community extends Model
{
public function addresses(){
return $this->belongsToMany(Address::class, 'community_address', 'community_id', 'address_id');
}
}
$community->addresses() 实际上只返回社区的地址,但说我想在数据透视表中按地址类型过滤(账单、邮寄等)
我可以试试这个:
public function getBillingAddress(){
return $this->addresses()->wherePivot('is_billing','=', true)->firstOrFail()->get();
}
哪个确实返回结果,但是我的数据透视表中的每一行都与我的查询匹配,而不是在现有地址之外运行我的查询
所以我的第二个想法是像这样使用“and”布尔参数
public function getBillingAddress(){
return $this->addresses()->wherePivot('community_id', '=', $this->id, true)->wherePivot('is_billing','=', true)->firstOrFail()->get();
}
这导致以下 SQL 出错(出于明显的原因),但看起来也不太像是在搜索我想要的东西,即使它确实有效?
select `addresses`.*, `community_address`.`community_id` as `pivot_community_id`, `community_address`.`address_id` as `pivot_address_id` from `addresses` inner join `community_address` on `addresses`.`id` = `community_address`.`address_id` where `community_address`.`community_id` = 2 1 `community_address`.`community_id` = 2 and `community_address`.`is_billing` = 1 limit 1
在我看来,“and”值实际上不是布尔值,而是将值作为字符串直接打印到查询中。
我尝试了显而易见的方法,并尝试用“and”交换第四个参数,并生成了以下 sql,它不会失败,但会返回所有地址,而不仅仅是链接到我的社区的地址
select `addresses`.*, `community_address`.`community_id` as `pivot_community_id`, `community_address`.`address_id` as `pivot_address_id` from `addresses` inner join `community_address` on `addresses`.`id` = `community_address`.`address_id` where `community_address`.`community_id` = 2 and `community_address`.`community_id` = 2 and `community_address`.`is_billing` = 1 limit 1)
我在这里遗漏了一些明显的东西吗?
通过对结果 SQL 进行一些修补,我可以获得我想要的,这是以下原始 sql 查询:
select `addresses`.*,
`community_address`.`community_id` as `pivot_community_id`,
`community_address`.`address_id` as `pivot_address_id`
from `addresses`
inner join `community_address` on `addresses`.`id` = `community_address`.`address_id` and `community_address`.`community_id` = 2 and `community_address`.`is_billing` = 1
limit 1
如何通过 eloquent 实现为我生成的相同 SQL?
似乎我误解了如何wherePivot()
工作,将代码更改为以下工作:
public function getBillingAddress(){
return $this->addresses()->wherePivot('is_billing', '=', true)->get()->first->all();
}
新代码试图调用数据透视表的 is_billing 列以进一步过滤现有表,旧代码试图通过已经过滤的内容对其进行过滤,但由于它是内连接,因此返回所有行(至少我认为?)
无论哪种方式,这都解决了,希望这可以帮助将来的某人。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句