Laravel Красномовний: Як отримати лише певні стовпці з об'єднаних таблиць


102

У мене є 2 об'єднані таблиці в Красномовних, а саме теми та користувачі.

тема теми:

public function user() {
  return $this->belongs_to('User');
}

модель користувача:

public function themes() {
  return $this->has_many('Theme');
}

Мій красномовний дзвінок api виглядає нижче:

return Response::eloquent(Theme::with('user')->get());

Який повертає всі стовпці з теми (це нормально), а всі стовпці від користувача (не добре). Мені потрібен лише стовпець "ім'я користувача" з моделі користувача, як я можу обмежити запит на це?


Я працюю над подібним завданням, чи можу я знати, чи використовую я Responseклас, який мені потрібно імпортувати?
Агнес Паліт

Відповіді:


103

Змініть модель, щоб вказати, які стовпці ви вибрали:

public function user() {
  return $this->belongs_to('User')->select(array('id', 'username'));
}

І не забудьте включити колонку, до якої ви приєднуєтесь.


6
чудова відповідь, також підказка про включення стовпця приєднала мені тону часу!
greatwitenorth

Що робити, якщо в деяких місцях мені потрібен лише id замість ідентифікатора та імені користувача? Ще потрібно вибрати обидва?
Дарій.V

Привіт, функція вибору має таку ж функцію в конструкторі запитів моделі?
Gokigooooks

4
Я не думаю, що це хороший підхід. Це буде на зразок жорсткого кодування назв стовпців. Усі місця повернуть лише ці стовпці. У деяких інших api мені можуть знадобитися ще кілька стовпців, щоб тут не працювало. Я думаю, що тут використовується варіант QueryBuilder.
Аман Сура

2
Це драматичний підхід, оскільки він відбуватиметься кожного разу, коли ви робите виклик вперед. Я вважаю, що відповідь Саджаджа Ашрафа - це найбільше зацікавлення людей.
MMMTroy

37

Для Laravel> = 5.2

Використовуйте метод -> pluck ()

$roles = DB::table('roles')->pluck('title');

Якщо ви хочете отримати масив, що містить значення одного стовпця, ви можете скористатися методом зривання


Для Laravel <= 5,1

Використовуйте метод -> списки ()

$roles = DB::table('roles')->lists('title');

Цей метод поверне масив назв ролей. Ви також можете вказати стовпчик спеціального ключа для повернутого масиву:


2
Це насправді не відповідь на питання (яке стосувалося конкретно стосунків / стосунків).
orrd

30

Ви можете надати масив полів у параметрі get так:

return Response::eloquent(Theme::with('user')->get(array('user.username'));

ОНОВЛЕННЯ (для Laravel 5.2) З документів ви можете це зробити:

$response = DB::table('themes')
    ->select('themes.*', 'users.username')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get();

2
Я спробував це, і він показує помилку, SQLSTATE[42S22]: Column not foundі SQL не включає таблицю в with. Sql, який відображається на помилці, є "SELECT fk_table.column1 FROM main_table".
Мішель Айрес

1
Це "users.username" (не "user.username"). Код у відповіді спрацює, якщо у вас є імена таблиці та стовпців, які відповідають вашій фактичній базі даних. Це недолік цього рішення, це побудова SQL-запиту, а не використання Eloquent, тому імена повинні відповідати вашим фактичним таблицям та стовпцям бази даних.
orrd

22

Я знаю, ви просите красномовний, але ви можете це зробити з Fluent Query Builder

$data = DB::table('themes')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get(array('themes.*', 'users.username'));

16

Ось як я це роблю

$posts = Post::with(['category' => function($query){
        $query->select('id', 'name');
      }])->get();

Перша відповідь користувача2317976 не працювала для мене, я використовую laravel 5.1


2
Актуальна відповідь = корисно!
thesunneversets

Дякую. Це прекрасно працює для мене. Я повинен додати іноземний ключ у операторі select, як ви робили з 'id', інакше він повернеться в нулевий.
Іман Седігі

Однак це все-таки отримує поле "зведення" для кожного результату, що містить обидва ідентифікатори (post_id та category_id), правда? Як я можу покататися на ньому?
mayid

1
@mayid ви можете спробувати додати pivotдо $ прихований масив Post Modelprotected $hidden = ['pivot']
Sajjad Ashraf

Це найкраще рішення (припускаючи, що ви використовуєте досить сучасну версію Laravel)
orrd

11

Іншим варіантом є використання $hiddenвластивості моделі, щоб приховати стовпці, які не потрібно відображати. Ви можете визначити цю властивість під час руху або встановити за замовчуванням для вашої моделі.

public static $hidden = array('password');

Тепер пароль користувачів буде приховано, коли ви повернете відповідь JSON.

Ви також можете встановити його на льоту подібним чином.

User::$hidden = array('password');

2
в Laravel 4.2 Я отримую "Не можу отримати доступ до захищеної власності користувача :: $ hidden" при спробі встановити це динамічно.
mtmacdonald

1
цього не повинно бути static.
StackOverflowed

@StackOverflowed, я вважаю, ви не звертали жодного повідомлення про те, скільки років це питання / відповідь і що це стосується Laravel 3.
Jason Lewis

10

Використання з пагинацією

$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->select('themes.*', 'users.username')
->paginate(6);

6

user2317976 ввів чудовий статичний спосіб вибору стовпців пов'язаних таблиць.

Ось динамічний трюк, який я знайшов, щоб ви могли отримати все, що завгодно, використовуючи модель:

return Response::eloquent(Theme::with(array('user' => function ($q) {
    $q->addSelect(array('id','username'))
}))->get();

Щойно я виявив, що цей трюк також добре працює з load (). Це дуже зручно.

$queriedTheme->load(array('user'=>function($q){$q->addSelect(..)});

Переконайтесь, що ви також включите ключ цільової таблиці, інакше він не зможе його знайти.


6

Сюди:

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();

Будь ласка, завжди поясніть свою відповідь.
Рохіт Гупта

Мав подібну проблему, це найрозумніший шлях поки що! Ця відповідь занижена!
eldblz

Це те саме, що відповідь, яку вже раніше подав Саджаджа Ашраф.
orrd

5

Я знаю, що це старе питання, але якщо ви будуєте API, як це робить автор запитання, використовуйте вихідні трансформатори для виконання таких завдань.

Transofrmer - це шар між вашим фактичним результатом запиту бази даних та контролером. Це дозволяє легко контролювати та змінювати те, що буде виведено користувачеві або споживачеві API.

Я рекомендую Fractal як міцну основу вашого вихідного шару трансформації. Ви можете прочитати документацію тут .



4

У Laravel 5.5 найчистіший спосіб зробити це:

Theme::with('user:userid,name,address')->get()

Ви додаєте двокрапку та поля, які хочете вибрати, відокремлені комою та без пробілу між ними.


Чи знаєте ви, як ми можемо отримати конкретний стовпець пов’язаної таблиці при використанні сторінки.
Даніял Насір

2

Використання моделі:

Model::where('column','value')->get(['column1','column2','column3',...]);

Використання програми для запитів:

DB::table('table_name')->where('column','value')->get(['column1','column2','column3',...]);

0

Якщо я добре зрозумів це, повертається добре, за винятком того, що ви хочете побачити лише одну колонку. Якщо так, це нижче повинно бути набагато простіше:

return Response::eloquent(Theme::with('user')->get(['username']));

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.