Как получить название страны для связанного города с помощью Laravel Eloquent - PullRequest
2 голосов
/ 28 октября 2019

Мне нужна помощь в моем проекте. У меня был компонент для городов. Существует связь между таблицей городов и таблицей стран по идентификатору, как получить название страны для каждого города в компоненте города

это мой кодв компоненте city

<table id="example" class="display" style="width:100%">
            <thead>
            <tr>
                <th>
                    <label class="form-checkbox">
                        <input type="checkbox" v-model="selectAll" @click="select">
                        <i class="form-icon"></i>
                    </label>
                </th>
                <th>#</th>
                <th>City Name</th>
                <th>Country Name</th>
                <th>Created At</th>
                <th>Updated At</th>
                <th>Edit</th>
                <th>Delete</th>

            </tr>
            </thead>
            <tbody>
            <tr v-if="cities.length > 0" v-for="(city,index) in cities" :id="city.id">
                <td>
                    <label class="form-checkbox">
                        <input type="checkbox" :value="city.id" v-model="selected">
                        <i class="form-icon"></i>
                    </label>
                </td>
                <td>{{index+1 }}</td>
                <td>{{city.name}}</td>
                <td></td>
                <td>{{city.created_at}}</td>
                <td>{{city.updated_at}}</td>
                <td><button class="btn btn-warning" @click="editModal=true;setVal(city.id,city.name,city.country)" data-toggle="modal" data-target="#editcity"><i class="fa fa-pen"></i></button></td>
                <td><button class="btn btn-danger" @click="delcity(city.id)"><i class="fa fa-trash"></i></button></td>


            </tr>
            </tbody>
            <tfoot>
            <tr>
                <th><label class="form-checkbox">
                    <input type="checkbox" v-model="selectAll" @click="select">
                    <i class="form-icon"></i>
                </label></th>
                <th>#</th>
                <th>City Name</th>
                <th>Country Name</th>
                <th>Created At</th>
                <th>Updated At</th>
                <th>Edit</th>
                <th>Delete</th>

            </tr>
            </tfoot>
        </table>

вторая часть кода в компоненте city

<script>
export default {
    data(){
        return {
            cities:         [],
            countries:      [],
            id:             '',
            name:           '',
            country_id:     '',
            country_name:   '',
            loading:        false,
            showModal:      false,
            editModal:      false,
            selected:       [],
            selectAll:      false,
            csrf:           document.querySelector('meta[name="csrf-token"]').getAttribute('content')
        }
    },
    methods:{
        getCities(){
            let url = '/dashboard/getCities';
            axios.get(url).then(res=>{
                let link = this;
                this.cities = res.data;
                /*this.cities.forEach(function(item) {
                    link.getCountryName(item.country_id);
                });*/
            })
        },
        getCountryName(id){
            axios.get('/dashboard/getCountryName/'+id).then(res=>{
                console.log(res.data.success);
                this.country_name = res.data.success;
            });
        },
        getCountries(){
            axios.get('/dashboard/getCountries').then(res=>{
                this.countries = res.data;
            })
        },

     },

    mounted() {
        this.getCities();
        this.getCountries();
    }
}

две функции getcities и получают название страны в городском контроллере

public function getCities(){
    $cities = City::orderBy('id','desc')->get();
    return response()->json($cities);
}
public function getCountryName($country_id){
    $country = DB::table('countries')->where('id','=',$country_id)->first();
    return response()->json(['success'=> $country->name],200);
}

Код отношения в модели страны

public function cities(){
    return $this->hasMany('App\Models\City');
}

Код отношения в модели города

public function countries(){
        return $this->hasMany('App\Models\City');
    }

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Я думаю, вы слишком усложняете то, что должно быть довольно простым. Если ваши Eloquent отношения настроены правильно, включить поля из модели Country в сериализацию связанной модели City довольно тривиально.

Ваши отношения должны выглядеть примерно такэто:

City.php

<?php

...

class City extends Model
{
  ...

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

Country.php

<?php

...

class Country extends Model
{
  ...

  public function Cities
  {
    return $this->hasMany('App\Models\City');
  }
}

ПРИМЕЧАНИЕ: Для этой настройки требуется столбец country_id в таблице cities

В настоящее время это отношение определено как много-ко-многим , что нене имеет особого смысла, учитывая контекст. A City не имеет много стран. Он принадлежит точно один Страна. С другой стороны все в порядке, поскольку у Country есть много городов. Таким образом, здесь вы хотите получить отношение один-ко-многим .

После правильной настройки отношений модели вы можете легко получить имя Country для любого City. Я бы сделал это так:

City.php

<?php

...

class City extends Model
{
  ...

  protected $with = ['country'];
}

Это означает, что каждый раз, когда City загружается из базы данных, его Country is нетерпеливо загружен .

В качестве альтернативы вы можете загружать соответствующие Country при загрузке всех городов:

citycontroller

public function getCities(){
    $cities = City::with('country')
                  ->orderBy('id','desc')
                  ->get();

    return response()->json($cities);
}

Независимо от того, какойРеализация, которую вы выбираете, ваш компонент City может получить доступ к полям Country через модель City:

<tr v-if="cities.length > 0" v-for="(city,index) in cities" :id="city.id">

  ...

  <td>{{ city.country.name }}</td>

  ...

</tr>
0 голосов
/ 28 октября 2019

Relationship code in City Model

обновите

public function countries()
{
  return $this->hasMany('App\Models\City');
}

до

public function country()
{
  // return $this->belongsTo('App\Models\Country');
  return $this->belongsTo(Country::class);
}

, указав способ переименования countries в country

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...