#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.