Laravel中数据透视表关联查询及特定国家支付配置获取的技术咨询
Laravel中数据透视表关联查询及特定国家支付配置获取的技术咨询
嘿,我来帮你搞定这个问题!你现在需要根据指定国家获取对应的Mobile Money支付配置,不管是用Laravel的Eloquent关联还是直接DB查询都能实现,我给你一步步拆解清楚:
一、使用Eloquent关联的方式(推荐,代码更易维护)
首先咱们得先把各个模型的关联关系定义好,因为你的数据结构里有多层关联,尤其是country_payment_method这个中间表还关联了payment_method_configurations,所以咱们需要给这个中间表创建一个自定义的Pivot模型,这样操作起来更灵活。
1. 定义模型及关联
(1)Country 模型
在Country模型里定义和支付方式的关联:
public function paymentMethods() { return $this->belongsToMany(PaymentMethod::class, 'country_payment_method') ->withPivot('is_active') ->using(CountryPaymentMethod::class); }
(2)自定义Pivot模型:CountryPaymentMethod
创建这个模型来关联支付配置表,同时直接关联移动网络和货币:
use Illuminate\Database\Eloquent\Relations\Pivot; class CountryPaymentMethod extends Pivot { protected $table = 'country_payment_method'; public $timestamps = false; // 如果你的表没加时间戳字段,加上这个 // 关联所有配置项 public function configurations() { return $this->hasMany(PaymentMethodConfiguration::class, 'country_payment_method_id'); } // 直接关联该支付方式下的所有移动网络 public function mobileNetworks() { return $this->belongsToMany(MobileNetwork::class, 'payment_method_configurations', 'country_payment_method_id', 'config_value') ->wherePivot('config_key', 'mobile_network_id'); } // 直接关联该国家支付方式对应的货币 public function currency() { return $this->belongsTo(Currency::class, 'config_value', 'id') ->where('config_key', 'currency_id') ->via('configurations'); } }
(3)PaymentMethodConfiguration 模型
这个模型就是对应payment_method_configurations表,很简单:
class PaymentMethodConfiguration extends Model { protected $table = 'payment_method_configurations'; public $timestamps = false; }
(4)其他基础模型(MobileNetwork、Currency、PaymentMethod)
这些模型不需要额外的特殊关联,保持基础的Model继承即可,比如:
class MobileNetwork extends Model { protected $table = 'mobile_networks'; public $timestamps = false; }
2. 执行查询获取配置
当你知道国家的iso_code或者id时,就可以这样查询:
// 比如获取爱尔兰的配置,用iso_code筛选 $country = Country::where('iso_code', 'IE')->firstOrFail(); // 获取该国家的Mobile Money支付方式及其所有配置 $mobileMoneyConfig = $country->paymentMethods() ->where('payment_methods.name', 'Mobile Money') ->with(['configurations', 'mobileNetworks', 'currency']) ->first(); // 之后你就可以直接获取需要的数据了: // 所有原始配置项 $allRawConfigs = $mobileMoneyConfig->configurations; // 对应的移动网络列表(直接是MobileNetwork模型实例) $mobileNetworks = $mobileMoneyConfig->mobileNetworks; // 对应的货币(直接是Currency模型实例) $currency = $mobileMoneyConfig->currency;
二、直接使用DB查询的方式(适合轻量查询,不需要模型关联)
如果你觉得定义模型关联有点繁琐,或者只是需要一次性查询数据,直接用DB门面查询也很高效,还能自定义需要的字段:
// 比如要查询英国(iso_code: UK)的Mobile Money配置 $targetCountryIso = 'UK'; $configs = DB::table('countries') ->join('country_payment_method', 'countries.id', '=', 'country_payment_method.country_id') ->join('payment_methods', 'payment_methods.id', '=', 'country_payment_method.payment_method_id') ->join('payment_method_configurations', 'country_payment_method.id', '=', 'payment_method_configurations.country_payment_method_id') // 关联移动网络表,筛选出配置项是mobile_network_id的记录 ->leftJoin('mobile_networks', function($join) { $join->on('payment_method_configurations.config_value', '=', 'mobile_networks.id') ->where('payment_method_configurations.config_key', '=', 'mobile_network_id'); }) // 关联货币表,筛选出配置项是currency_id的记录 ->leftJoin('currencies', function($join) { $join->on('payment_method_configurations.config_value', '=', 'currencies.id') ->where('payment_method_configurations.config_key', '=', 'currency_id'); }) // 筛选目标国家和Mobile Money支付方式 ->where('countries.iso_code', $targetCountryIso) ->where('payment_methods.name', 'Mobile Money') // 自定义需要返回的字段 ->select( 'countries.name as country_name', 'payment_method_configurations.config_key', 'payment_method_configurations.config_value', 'mobile_networks.name as mobile_network_name', 'currencies.name as currency_name', 'currencies.code as currency_code' ) ->get(); // 如果你想把结果整理成更友好的格式,比如按配置类型分组 $formattedConfig = [ 'mobile_networks' => $configs->where('config_key', 'mobile_network_id')->pluck('mobile_network_name', 'config_value'), 'currency' => $configs->where('config_key', 'currency_id')->first(['currency_name', 'currency_code']) ];
额外小提示
- 如果你不需要直接拿到移动网络和货币的模型实例,只是需要id的话,Eloquent关联里只加载
configurations就够了,不用加载mobileNetworks和currency。 - 用DB查询的时候,可以根据自己的需求增减
select里的字段,避免查询不必要的数据,提升性能。
内容来源于stack exchange
相关产品推荐
相关产品推荐

