teratail header banner
teratail header banner
質問するログイン新規登録
Laravel 6

Laravel 6は、オープンソースなPHPのフレームワーク。Webアプリケーションの開発に適しており、バージョン6はLTSです。5.8での向上に加えて、セマンティックバージョニングの採用やLaravel Vaporとのコンパチビリティなどが変更されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1334閲覧

テーブル内の重複しているデータを一つだけ表示する方法が分からないです。

haruatu

総合スコア89

Laravel 6

Laravel 6は、オープンソースなPHPのフレームワーク。Webアプリケーションの開発に適しており、バージョン6はLTSです。5.8での向上に加えて、セマンティックバージョニングの採用やLaravel Vaporとのコンパチビリティなどが変更されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2022/02/15 19:41

編集2022/02/16 04:36

0

1

1,前提・実現したいこと

検索ボックスに入力した文字を含む本のタイトルをbooksテーブルから探して、該当する本のタイトルと本の表紙の画像を表示する検索機能を作ることが前提。また、本のタイトルか画像をクリックすることでその本を評価するペ-ジに飛べるようになっています(booksテーブルのidで識別)。

2, 発生している問題・エラーメッセージ

表示することは出来たが、重複しているデータが全て表示されてしまうため、同じ本のタイトルと表紙が何回も表示されて困っています。

3, 該当のソースコード

BookController.php

//検索結果の表示 public function searchExecute(Request $request ) { $keyword = $request->input('booklist'); $request->validate(['booklist' => 'required'],['booklist.required'=>'入力が空白です']); //検索ボタンが押された時の処理 if(isset($request["booklist"])) { //入力チェック if(!empty("booklist")) { //本のidとタイトルと筆者名と画像をグループ化 $groupby = Book::select('id','title','author','largeImageUrl')->groupBy('title')->groupBy('author')->groupBy('id')->groupBy('largeImageUrl'); //タイトルをあいまい検索 $title = $groupby->where('title','like', '%' .$keyword. '%')->paginate(10)->appends($request->except(['user_id'])); return view('searchExecute')->with([ 'title' => $title ]); } } }

searchExecute.blade.php

@foreach($title as $book) <div class='booktitle'> @if($book->largeImageUrl == NULL)//表紙の画像がなければこっち    //本のタイトルと画像を<a>タグで囲って、テーブルのidで識別 <a href="/books/{{$book->id}}"><img src="{{$book->largeImageUrl = 'https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/noimage_01.gif?_ex=200x20'}}" width="250" height="300"></a> <a href="/books/{{$book->id}}"><p>{{Str::limit($book->title,30)}}</p></a> @else //表紙の画像があればこっち    //本のタイトルと画像を<a>タグで囲って、テーブルのidで識別 <a href="/books/{{$book->id}}"><img src="{{$book->largeImageUrl}}" width="250" height="300"></a> <a href="/books/{{$book->id}}"><p>{{Str::limit($book->title,30)}}</p></a> @endif </div> @endforeach

ScoreController.php

//クリックした本のタイトルのidを取得&ブックマークボタンの実装 public function search(Book $book,Bookmark $bookmark) { $id = $book->id; $bookmark=Bookmark::where('book_id',$id)->exists(); return view('score')->with(['book'=>$book, 'bookmark'=>$bookmark]); }

4, 自分で調べたことや試したこと

BookController.phpのselectをid無しで試してみたのですが、重複したデータが一回しか出てこなくなった代わりに、上述の[1,前提・実現したいこと]の太文字で書いてある部分の機能が出来なくなってしまった為、やめました。

5, 使っているツールのバージョンなど補足情報

バージョンはPHPのlaravel6です。

--追記--

booksテーブル

MariaDB [book]> desc books; +---------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | link | varchar(255) | YES | | NULL | | | author | varchar(255) | NO | | NULL | | | category | varchar(255) | YES | | NULL | | | guid | text | YES | | NULL | | | isbn | varchar(255) | YES | | NULL | | | booksGenreId | varchar(255) | YES | | NULL | | | publisherName | varchar(255) | YES | | NULL | | | largeImageUrl | text | YES | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +---------------+------------------+------+-----+---------+----------------+ 12 rows in set (0.01 sec)

booksテーブルの中身は下記のようにしてAPIの情報を保存しています。

$bookbook = []; //二つのAPIの情報を整理 for($i=0;$i<count($books);$i++) { $books[$i] += ["isbn" => null]; $books[$i] += ["booksGenreId" => null]; $books[$i] += ["publisherName" => null]; $books[$i] += ["largeImageUrl" => null]; array_push($bookbook,$books[$i]); } for($i=0;$i<count($rakutenn_books);$i++) { $rakutenn_books[$i]['Item'] += ["guid" => null]; $rakutenn_books[$i]['Item'] += ["link" => null]; $rakutenn_books[$i]['Item'] += ["category" => null]; array_push($bookbook,$rakutenn_books[$i]['Item']); } //これが登録 foreach($bookbook as $item) { Book::create([ 'title'=>$item['title'], 'link'=>$item['link'], 'author'=>$item['author'], 'category'=>$item['category'], 'guid'=>$item['guid'], 'isbn'=>$item['isbn'], 'booksGenreId'=>$item['booksGenreId'], 'publisherName'=>$item['publisherName'], 'largeImageUrl'=>$item['largeImageUrl']]); }

DBにあるデータの説明はこれで大丈夫でしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

phper.k

2022/02/16 02:27

DBにどんなデータがあるのかわからないと回答できません
退会済みユーザー

退会済みユーザー

2022/02/16 02:47

同じ書籍を一つのidで統一して扱いたいのか、同一書籍だけど画像の有無で別ものとして扱いたいのかによっても状況は変わってきそうです。
退会済みユーザー

退会済みユーザー

2022/02/16 04:55

> また、本のタイトルか画像をクリックすることでその本を評価するペ-ジに飛べるようになっています(booksテーブルのidで識別) 同じ書籍名の本に対して複数の異なるidが割り振られるようなテーブル構造になっていますが、このidをつかって評価ページに飛ぶと同じ本でもidごとに評価が分かれてしまうのではないでしょうか。
haruatu

2022/02/16 04:56

「DBにどんなデータがあるのかわからないと回答できません」ー>質問文に追記しておきました。 「同じ書籍を一つのidで統一して扱いたいのか、同一書籍だけど画像の有無で別ものとして扱いたいのかによっても状況は変わってきそうです。」 ー>すいません、私の説明不足です。「同一書籍だけど画像の有無で別ものとして扱いたいのか」についてなんですが、同一書籍の場合、画像の有無も同じなため不可能となっています。 「同じ書籍を一つのidで統一して扱いたいのか」に関してなのですが、その方法を教えていただけると幸いです。
haruatu

2022/02/16 05:11

>同じ書籍名の本に対して複数の異なるidが割り振られるようなテーブル構造になっていますが、このidをつかって評価ページに飛ぶと同じ本でもidごとに評価が分かれてしまうのではないでしょうか。 はい、その通りです。そういった意味でも困っています。
退会済みユーザー

退会済みユーザー

2022/02/16 05:13

isbnって多分それぞれの本に対して一意にわりふられますよね(自分の認識間違いがあったらすみません) その認識があっているのであれば、isbnを主キー(PRIMARY KEY)に設定し、今あるidは主キー設定しないようにすればよいかと思います。
退会済みユーザー

退会済みユーザー

2022/02/16 05:48

それか、isbnに対してユニーク制約をかけて、同じisbnを登録しようとしたらエラーにするとかでしょうか。
haruatu

2022/02/16 15:14

返信が遅くなり申し訳ありません。 >isbnって多分それぞれの本に対して一意にわりふられますよね その認識で合っています。ただ少しだけ困ったことがありまして、booksテーブルは二つのAPIの情報を登録しているのですが、そのうちの片方の[国立国会図書館サーチ API]には、そもそもisbnの情報がなく、どうしようかと困っているところです
退会済みユーザー

退会済みユーザー

2022/02/16 23:40

データ登録の流れがわからないのでここからは抽象的な話しかできないですが、 その本を一意に特定できる情報があれば、それをキーにするのが基本的な方針です。 あとはSQLにこだわらず、登録時のPHP側の処理で重複しないよう対応するというのもアリです。 ただそれをやるにしても、これから登録しようとしている本の情報がすでに登録済みかどうかを確認しなければならないため、いずれにしても対象の本を一意に確定する何らかの情報はどうしても必要になりますね。
haruatu

2022/02/17 02:09

なるほど、わかりました。
haruatu

2022/02/18 06:41

解決しました。 お二方とも質問に答えてくださりありがとうございました。
guest

回答2

0

自己解決

解決することが出来ました。

[searchExecute.blade.php]の

@foreach($title as $book)を@foreach($title->unique('title') as $book)と変更することで検索結果の重複しているデータを非表示にすることが出来ました。

uniqueは対象とするデータに重複しているデータがあった場合それを消してくれる役割があるそうです。
今回の場合だと、$title->unique('title')は言葉に直すと「[BookController.php]の処理を通して渡された$titleの'title'に重複しているデータがある場合、重複している分だけ非表示にする」という意味になります。

投稿2022/02/19 08:34

haruatu

総合スコア89

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

selectする際にlimit 1が設定できれば1件だけ取得されるようになります。

投稿2022/02/16 02:40

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haruatu

2022/02/16 05:08

質問に答えてくださりありがとうございます。 $groupby = Book::select('id','title','author','largeImageUrl')->groupBy('title')->groupBy('author')->groupBy('id')->groupBy('largeImageUrl')->limit(1); という風に追加してみたのですが、変化はありませんでした。
haruatu

2022/02/18 06:40

解決しました。 質問に答えてくださりありがとうございました。
退会済みユーザー

退会済みユーザー

2022/02/18 06:53

差し支えなければ最終的にどういった形で解決したかも記載いただけますか?
haruatu

2022/02/19 08:36

遅くなってすみません。 解決方法を載せました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問