【问题标题】:How to get country, region, town and area name for a user provided area_id migrates to user tables如何获取用户提供的国家、地区、城镇和地区名称 area_id 迁移到用户表
【发布时间】:2018-10-01 01:08:12
【问题描述】:

我想使用迁移到属于特定用户的用户表的 area_id 获取区域、城镇、地区和国家/地区的名称。

我有 5 张桌子,其中包括,

带有 id、名称和描述的 Country 表。

带有 id、name、description 和 country_id 的 Region 表

带有 id、name、description 和 region_id 的 Town 表。

带有 id、name、description 和 town_id 的 Area 表。

我有一个用户表,其中 area_id 的值迁移到用户表并具有属性 id、name、surname、email、phone、area_id。

如果 area_id 存在于使用 Laravel 的数据库中的用户表中,我想知道如何获取特定用户的地区、城镇、地区和国家/地区的名称。

在我的用户控制器中,我做了这样的事情

 /**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */

public function accueil(Session $session)
{
    $recentJobbers =User::with('Area')
        ->limit(5)
         ->whereType('jobber')
        ->orderBy('updated_at', 'desc')
        ->get();

    return view('home', compact('recentJobbers','areas', 'categories'));
}

在我的刀片视图的一部分中,我这样做了

 <div class="col-lg-12">
                    <div class="heading">
                        <h2>Jobbeurs en vedette</h2>
                        <span>Principaux jobbers ayant déjà  été solicités pour leur travail.</span>
                    </div><!-- Heading -->
                    <div class="job-listings-sec">

                        @foreach($recentJobbers as $recentJobber)
                        <div class="job-listing">
                            <div class="job-title-sec">
                                <div class="c-logo"> <img src="{{url('images/avatars/'. $recentJobber->photo) }}" alt="Image" /> </div>
                                <h3><a href="{{ route('profileDetails', ['id'=>$recentJobber->id]) }}" title="">{{ $recentJobber->name }} {{ $recentJobber->surname }} <span style="float:right; padding-left: 10px;">(a ete contacte 25 fois)</span></a></h3>
                                <span>{{ $recentJobber->title }}</span>
                            </div>
                            <span class="job-lctn"><i class="la la-map-marker"></i>{{ $recentJobber->area->name }}, {{ $recentJobber->town->name }}, {{ $recentJobber->region->name }}</span>
                            <span class="fav-job"><i class="la la-heart-o"></i></span>
                            <a href="{{ route('profileDetails', ['id'=>$recentJobber->id]) }}" class="job-is ft">Voir Profil</a>
                        </div><!-- Job -->
                        @endforeach
                    </div>
                </div>

在我的用户模型中,我做了类似的事情

  public function category() 
{
    return $this->belongsTo('App\Category');
}

public function service() 
{
    return $this->belongsTo('App\Service');
}

 public function region() 
{
    return $this->belongsTo('App\Region');
}

public function town() 
{
    return $this->belongsTo('App\Town');
}

 public function area() 
{
    return $this->belongsTo('App\Area');
}

但它只返回区域名称。不返回城镇、地区或国家名称。

我想知道实现这一目标的最简单方法是什么。欢迎任何帮助

【问题讨论】:

    标签: sql laravel laravel-5 relationship


    【解决方案1】:

    您可以做的是在每个模型上建立关系 - 不是所有模型都在 User

    class Region extends Model
    {
        protected $fillable = ['country_id', 'name', 'description'];
    
        public function country(): BelongsTo
        {
            return $this->belongsTo(Country::class);
        }
    }
    
    class Town extends Model
    {
        protected $fillable = ['region_id', 'name', 'description'];
    
        public function region(): BelongsTo
        {
            return $this->belongsTo(Region::class);
        }
    }
    
    class Area extends Model
    {
        protected $fillable = ['town_id', 'name', 'description'];
    
        public function town(): BelongsTo
        {
            return $this->belongsTo(Town::class);
        }
    }
    
    class User extends Authenticatable
    {
        // ...
    
        public function area(): BelongsTo
        {
            return $this->belongsTo(Area::class);
        }
    }
    

    然后要获得所有这些关系,您可以像这样使用急切加载:

    $recentJobbers = User::with('area.town.region.country')
            ->limit(5)
            ->whereType('jobber')
            ->orderBy('updated_at', 'desc')
            ->get();
    

    现在您可以通过以下方式访问每条记录上的这些:

    $recentJobber->area->town->region->country->name;
    $recentJobber->area->town->region->name;
    $recentJobber->area->town->name;
    $recentJobber->area->name;
    

    确保您使用如上所示的预加载 - 否则在每次迭代中获取这些关系将非常昂贵。以下是有关该主题的一些附加信息:https://laravel.com/docs/5.6/eloquent-relationships#eager-loading

    为了让它看起来更好看,你可以在你的 User 模型中添加访问器

    class User extends Authenticatable
    {
        // ...
    
        public function area(): BelongsTo
        {
            return $this->belongsTo(Area::class);
        }
    
        public function getTownAttribute(): Town
        {
            return $this->area->town;
        }
    
        public function getRegionAttribute(): Region
        {
            return $this->area->town->region;
        }
    
        public function getCountryAttribute(): Country
        {
            return $this->area->town->region->country;
        }
    }
    

    然后像在您的视图示例中那样调用它

    $recentJobber->country->name;
    $recentJobber->region->name;
    $recentJobber->town->name;
    $recentJobber->area->name;
    

    这是一个支持上述的测试

     /**
     * @test
     */
    public function pulls_area_town_region_and_country()
    {
        $country = Country::create([
            'name' => 'United Kingdom',
            'description' => 'United Kingdom'
        ]);
    
        $region = Region::create([
            'country_id' => $country->id,
            'name' => 'Somerset',
            'description' => 'Somerset'
        ]);
    
        $town = Town::create([
            'region_id' => $region->id,
            'name' => 'Bristol',
            'description' => 'Bristol'
        ]);
    
        $area = Area::create([
            'town_id' => $town->id,
            'name' => 'South',
            'description' => 'South'
        ]);
    
        factory(User::class)->create([
            'area_id' => $area->id
        ]);
    
    
        $user = User::with('area.town.region.country')->first();
    
        $this->assertEquals('United Kingdom', $user->area->town->region->country->name);
        $this->assertEquals('Somerset', $user->area->town->region->name);
        $this->assertEquals('Bristol', $user->area->town->name);
        $this->assertEquals('South', $user->area->name);
    
        $this->assertEquals('United Kingdom', $user->country->name);
        $this->assertEquals('Somerset', $user->region->name);
        $this->assertEquals('Bristol', $user->town->name);
        $this->assertEquals('South', $user->area->name);
    }
    

    【讨论】:

    • 非常感谢,先生。这段代码非常好,简单,解释清楚,正是我想要的。这不知道该多谢你。你真的节省了我的时间。最后一件事,这个 area(): BelongsTo 在这段代码中的作用是什么?
    • 不客气 - 很高兴我能帮上忙。它是返回类型声明 - 它基本上指示返回什么方法 - 在这种情况下,它将是 \Illuminate\Database\Eloquent\Relations\BelongsTo 的实例 - 所以请确保在每个模型类定义的顶部导入这些类使用 Illuminate \Database\Eloquent\Relations\BelongsTo - 或者你可以删除它。这是此功能的链接php.net/manual/en/…
    • 非常感谢,我已经添加了它,它工作得非常完美。很抱歉打扰,但我还有另一个非常相似的问题。你能检查一下吗? stackoverflow.com/questions/49944987/…
    • 刚刚发布了另一个问题的答案。
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    相关资源
    最近更新 更多