【问题标题】:Laravel 4 eloquent - Getting the id of self based on constraints of parentsLaravel 4 eloquent - 根据父母的约束获取自我的身份
【发布时间】:2024-10-25 01:10:02
【问题描述】:

我需要根据父母的约束来获取一行的 ID。我想使用 eloquent 来做到这一点并保持优雅。此过程开始时需要注意的一些事项: 我有 - country_code(2 digit iso), lang_code(2 digit 语言缩写) 我需要 - country_id,lang_id(主键) 所以我可以得到 - market_id(最后一次查询需要)

我可以通过以下方式检索我需要的数据,抱歉变量的命名(客户端有奇怪的名称):

// Only receive desired inputs
$input_get = Input::only('marketCode','langCode');

// Need the country based on the "marketCode"
$countryId = Country::where('code',$input_get['marketCode'])->pluck('id');

// Get the lang_id from "langCode"
$languageId = Language::where('lang_abbr',$input_get['langCode'])->pluck('lang_id');

// Get the market_id from country_id and lang_id
$marketId = Market::where('country_id', $countryId)
                  ->where('lang_id',$languageId)->pluck('market_id');

// Get All Market Translations for this market
$marketTranslation = MarketTranslation::where('market_id',$marketId)->lists('ml_val','ml_key');

我尝试了以下方法,但这只会根据限制急切加载国家/地区和语言。仅当 market_id 已知时,急切加载似乎才有帮助。

class Market extends Eloquent {
    protected $primaryKey = 'market_id';

    public function country() {
        return $this->belongsTo('Country');
    }

    public function language(){
        return $this->belongsTo('Language','lang_id');
    }
}


$markets = Market::with(array(
    'country' => function($query){
        $query->where('code','EE');
    },
    'language'=> function($query){
        $query->where('lang_abbr','et');
    }
))->get();

【问题讨论】:

    标签: php laravel eager-loading laravel-4 eloquent


    【解决方案1】:

    您必须使用连接才能做到这一点。

    $market = Market::join( 'countries', 'countries.id', '=', 'markets.country_id' )
        ->join( 'languages', 'languages.id', '=', 'markets.language_id' )
        ->where( 'countries.code', '=', 'EE' )
        ->where( 'languages.lang_abbr', 'et' )
        ->first();
    
    echo $market->id;
    

    如果这是经常发生的事情,那么我可能会在 Market 模型中添加一个静态方法。

    // in class Market
    public static function lookup_id( $country_code, $language_abbreviation ) { ... }
    
    // then later
    $market_id = Market::lookup_id( 'EE', 'et' );
    

    【讨论】:

    • 感谢您的回复。我探索了这个选项,但真的不想做手动连接或查询。我真的很想依赖关系和 ORM。我发布了我想出的解决方案。
    【解决方案2】:

    因此,在查看了关系之后,我能够在不使用手动联接或查询的情况下使其正常工作,而只需使用 ORM 中定义的关系。这似乎是正确的,因为它使用预先加载并过滤集合中所需的数据。

        // Get A country object that contains a collection of all markets that  use this country code
        $country = Country::getCountryByCountryCode('EE');
    
        // Filter out the market in the collection that uses the language specified by langCode
        $market = $country->markets->filter(function($market) {
            if ($market->language->lang_abbr == 'et') {
                return $market;
            }
        });
    
        // Get the market_id from the market object
        $marketId = $market->first()->market_id;
    

    模型和关系如下所示:

    class Country extends Eloquent {
    
        public function markets() {
            return $this->hasMany('Market')->with('language');
        }
    
        public static function getCountryByCountryCode($countryCode)
        {
            return Country::with('markets')->where('code',$countryCode)->first();
        }
    }
    
    class Market extends Eloquent {
        protected $primaryKey = 'market_id';
    
        public function country() {
            return $this->belongsTo('Country');
        }
    
        public function language(){
            return $this->belongsTo('Language','lang_id');
        }
    
    }
    
    
    
    class Language extends Eloquent {
    
        protected $primaryKey = 'lang_id';
    
    }
    

    【讨论】: