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.