Как получить «имя» из таблицы Prefs при извлечении пользователя и связанных с ним данных через пользовательские настройки?

#php #laravel #eloquent

#php #laravel #красноречивый

Вопрос:

Я использую Laravel 5.8 и пытаюсь выяснить, как определить отношения и получить нужные данные.

У меня есть эти три таблицы.

 Users: id, name, email
  
 Preferences: id, name
  

Пример данных,

 1, Vegetarian Only
2, Non-Veg Only
3, No preferences
4, Vegan Only
  
 UserPreferences: id, user_id,preference_id, approved ('Yes', 'No')
  

Я хочу получить доступ ко всем настройкам учетной записи пользователя. Это мои классы моделей.

 class User extends Model
{
    public function preferences()
    {
        return $this->hasMany('AppUserPreference', 'user_id', 'id'); 
        //model, foreign_key, local_key
    }
}

class Preference extends Model
{
  // just default empty model class
}

class UserPreference extends Model
{
 // just default empty model class
}
  

Когда я делаю

 $user = User::find(134);
$pref = $user->preferences()->get();
dd($pref);
  

Когда я это делаю, $pref = $user->preferences()->get(); оно включает в себя все поля из таблицы пользовательских настроек выше, но я также хочу включить name в качестве prefName из preferences таблицы.

Я не уверен, как это сделать. Можете ли вы, пожалуйста, помочь мне правильно определить отношения?

Обновить

По сути, $pref = $user->preferences()->get(); выполняется запрос типа SELECT * FROM UserPrefererences WHERE user_id=134

Тем не менее, я хочу иметь возможность получить результат, аналогичный этому запросу — SELECT *, pf.name pref_name FROM UserPrefererences upf INNER JOIN Preferences pf ON pf.id = upf.preference_id WHERE upf.user_id=134

Комментарии:

1. Вы имеете в виду, что вам нужен дополнительный столбец из настроек.

2. Да, пожалуйста, взгляните на мое обновление выше в моем вопросе.

3. Означает ли вышесказанное, что пользователь может иметь одни и те же предпочтения несколько раз?

4. @apokryfos — Нет — нет повторяющихся настроек для пользователя, но у них может быть несколько разных настроек. По сути, настройки — это список. Администратор может назначить одно или несколько предпочтений из этого списка любой учетной записи пользователя.

Ответ №1:

Единственная причина, по которой вы определяете свои отношения таким образом, — разрешить одну и ту же user_id, preference_id пару. Если вам это не нужно, вам следует преобразовать вашу user_preferences таблицу в сводную таблицу. Вот что вы делаете:

1) Удалите id столбец из user_preferences

2) Полностью удалите UserPreference класс

3) Определите ваши отношения, как показано ниже:

 class User extends Model
{
    public function preferences()
    {
        return $this->belongsToMany('AppPreference')->withPivot('approved'); 
    }
}
  

Затем вы можете сделать:

 $prefs = $user->preferences;
$prefs->first()->name;  //Here it is
$prefs->first()->pivot->approved; //The approved value
  

В случае, если вы все еще хотите сохранить UserPreferences , вы можете сделать следующее:

 class User extends Model
{
    public function preferences()
    {
        return $this->hasMany('AppUserPreference', 'user_id', 'id'); 
        //model, foreign_key, local_key
    }
}

class UserPreference extends Model
{
       public function preference() {
           return $this->belongsTo('AppPreference');
       }
}
  

Затем вы можете сделать:

 $prefs = $user->preferences()->with('preference')->get();
$prefs->first()->preference->name; //here it is
  

Комментарии:

1. Спасибо — позвольте мне попробовать это. Также, могу ли я получить все эти данные в одной строке, чтобы передать одну переменную в мой файл blade? Например. dd($user) … выводил бы array('id' =>1, "name" => "Joe", "preferences" => array("id" => 4, "user_id" =>1, "prefName" => "Veg Only"))

2. @NoNice Я написал другой ответ, который, я думаю, будет работать лучше. Во всяком случае, если вы определяете user_preferences как сводную таблицу, вы избегаете аномалий, таких как тот же пользователь, имеющий одинаковые предпочтения несколько раз, например, пользователь может быть веганом 3 раза (что, я думаю, не имеет смысла)

3. Да, ваш первоначальный ответ сработал для меня. Я смог определить отношение, но не знал, как получить значение, поэтому $prefs = $user->preferences()->with('preference')->get(); $prefs->first()->preference->name; это помогло мне понять, как это получить. так что спасибо вам за это.

4. Кроме того, я вижу, что вы снова используете pivot. Однако у меня есть существующее приложение, отличное от laravel, использующее ту же базу данных, поэтому я не смогу изменить схему. Но я уверен, что буду иметь это в виду для будущей новой разработки. Хотя сначала мне нужно разобраться, как это работает.

5. ДА. Вы можете изменить это как 2-й параметр belongsToMany.