質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.46%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

2回答

1222閲覧

DBからデータを取得するコードに改善の余地があるか知りたい

yuina711

総合スコア9

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

2クリップ

投稿2021/05/23 13:04

編集2021/05/24 06:06

###改善の余地があるか知りたいコード

php

1class Article extends Model 2{ 3 4public function countArticleDate() 5 { 6 // articlesテーブルからcreated_atカラムを指定して全件取得(all()で配列化) 7 $created_at_columns = $this->select('created_at')->get()->all(); 8 9 // 取得した件数分、繰り返し処理でフォーマットを変更、空の配列に格納 10 $count = count($created_at_columns); 11 for ($i = 0; $i < $count; $i++) { 12 $created_at[] = $created_at_columns[$i]->created_at->format('Y_m_d'); 13 } 14 // 重複しているデータ(日付)を除外 15 $unique_created_at = array_unique($created_at); 16 // 重複なしのデータ(日付)を数える 17 $count_created_at = count($unique_created_at); 18 // 合計値をコントローラーに渡す 19 return $count_created_at; 20 } 21}

###articlesテーブルの構造とcreated_atカラムの情報
articlesテーブル

iduser_idbodycreated_atupdated_at
11テスト2021-05-18 11:02:382021-05-18 11:02:38
`created_at` timestamp NULL DEFAULT NULL,

###取得結果(dd()で確認)

created_atカラムの日付データのフォーマット変更時と変更後、重複している日付データの削除後の合計値をdd()で確認

//フォーマットの変更成功 array:2 [▼ 0 => "2021_05_18" 1 => "2021_05_22" ] //count()で合計値の取得成功 2

上記のメソッドは、articlesテーブルからcreated_atカラムの日付データを日付重複なしで取得後、created_atカラム(日付データ)の合計値を取得したいと思い、日付データの重複をなくす為に、繰り返し処理で時刻を削除したフォーマット(年/月/日の状態)に変更した後にarray_unique()で重複を削除、そしてcount()で合計値を取得すると考え作成しました。

最終目的としましては、重複なしの日付単位で数えた投稿データの合計値をユーザーの投稿累計日数として表示したいと考えております。

例えば、ログインしているユーザーが、2021-05-18、2021-05-19、2021-05-20という日付データを保持している投稿を各日付ごとに2つずつ投稿していると仮定します。

このような場合、articlesテーブルでは、2021-05-18、2021-05-19、2021-05-20の投稿データが各2つずつ存在しているのでデータ数としては6つあることになると思います。

重複なしの日付単位で考えるとユーザーが投稿しているデータは3つになると思います。この重複なしの日付単位で数えた投稿データ数をユーザーの累計投稿日数として扱いたく、累計投稿日数3日という数をarticlesテーブルから取得したいと思い、上記のようなコードを作成致しました。

投稿している日数の合計値を表示したいユーザーとリレーションしているarticlesテーブルのcreated_atカラムを、一旦全て取得してその件数分の繰り返し処理で、取得したcreated_atカラムの日付データのフォーマットを変更していることが非常に効率が悪いと思っています。私自身の力ではこのコードに対する改善策が思いつきませんでした。

上記コードの改善点、間違い等のアドバイスをいただきたく存じます。

何卒、よろしくお願いします。

###追記
回答者様から、上記のコードは全て間違っているとのご指摘を受けました。
私、独学で学習しておりまして、学習してきたことが正しくないと言われどの箇所が間違っているのか分からない状態です。
指摘を真摯に受け止め、基礎固めからやり直したいと思っておりますので、もし可能であれば少し具体的に間違いをご指摘いただきたく存じます。

何卒、よろしくお願い致します。

###開発環境
laravel 6.20.16
php 7.4.15
MySQL 5.7

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

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

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

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

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

phper.k

2021/05/23 13:23 編集

countArticleDate() がどのクラスに描かれたものなのか、Controller ? Model ? そういう情報なしにアドバイスは困難ですよね?
yuina711

2021/05/24 01:34

申し訳ございませんでした。 修正しておきます。
yuina711

2021/05/24 03:35 編集

再度、質問内容の不備をご指摘くださりありがとうございます。 質問内容を修正いたしました。 お手数をおかけして申し訳ございませんでした。
phper.k

2021/05/24 05:19

> リレーションしているユーザーの投稿している日数の合計値として使用したいと考えております。 ログインしているユーザーの投稿の日付ごとの投稿数を表示したいということ? 日付の合計っておかしいと思うので。
yuina711

2021/05/24 06:03 編集

分かりにくい文章で申し訳ございません。 > ログインしているユーザーの投稿の日付ごとの投稿数を表示したいということ? 重複なしの日付単位で数えた投稿データの合計値をユーザーの累計投稿日数として表示したいと考えております。 例えば、ログインしているユーザーが、2021-05-18、2021-05-19、2021-05-20という日付データを保持している投稿を各日付ごとに2つずつ投稿していると仮定します。 このような場合、articlesテーブルでは、2021-05-18、2021-05-19、2021-05-20の投稿データが各2つずつ存在しているのでデータ数としては6つあることになると思います。 重複なしの日付単位で考えるとユーザーが投稿しているデータは3つになると思います。この重複なしの日付単位で数えた投稿データ数をユーザーの累計投稿日数として扱いたく、この累計投稿日数3日という数をarticlesテーブルから取得したいと思い、上記のようなコードを作成致しました。 再度、説明にご不明な点がございましたら、何なりとおっしゃってください。 何度もやりとりしてくださりありがとうございます。
guest

回答2

0

ベストアンサー

それぞれ、わからないところはリファレンスを確認するべし。

routing

php

1Route::resource('articles', 'ArticleController');

migration

php

1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7class CreateArticlesTable extends Migration 8{ 9 /** 10 * Run the migrations. 11 * 12 * @return void 13 */ 14 public function up() 15 { 16 Schema::create('articles', function (Blueprint $table) { 17 $table->bigIncrements('id'); 18 $table->unsignedBigInteger('user_id'); 19 $table->string('body'); 20 $table->timestamps(); 21 }); 22 } 23 24 /** 25 * Reverse the migrations. 26 * 27 * @return void 28 */ 29 public function down() 30 { 31 Schema::dropIfExists('articles'); 32 } 33}

factory

php

1<?php 2 3/** @var \Illuminate\Database\Eloquent\Factory $factory */ 4 5use App\Article; 6use Faker\Generator as Faker; 7 8$factory->define(Article::class, function (Faker $faker) { 9 return [ 10 'user_id' => function () { 11 return \App\User::query()->inRandomOrder()->first()->id; 12 }, 13 'body' => $faker->sentence 14 ]; 15});

seeder

php

1<?php 2 3use Illuminate\Database\Seeder; 4 5class UserSeeder extends Seeder 6{ 7 /** 8 * Run the database seeds. 9 * 10 * @return void 11 */ 12 public function run() 13 { 14 factory(\App\User::class, 10)->create()->each(function (\App\User $user) { 15 $user->articles()->saveMany( 16 factory(\App\Article::class, 100)->make() 17 ); 18 }); 19 } 20}

model

php

1<?php 2 3namespace App; 4 5use Carbon\Traits\Timestamp; 6use Illuminate\Database\Eloquent\Model; 7use Illuminate\Database\Eloquent\Relations\BelongsTo; 8 9class Article extends Model 10{ 11 use Timestamp; 12 13 /** 14 * @var string[] 15 */ 16 protected $fillable = [ 17 'user_id', 18 'body' 19 ]; 20 21 protected $appends = [ 22 'created_date' 23 ]; 24 25 /** 26 * @return string 27 */ 28 public function getCreatedDateAttribute(): string 29 { 30 return $this->created_at->format('Y-m-d'); 31 } 32 33 /** 34 * @return BelongsTo 35 */ 36 public function user(): BelongsTo 37 { 38 return $this->belongsTo(User::class); 39 } 40}

php

1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Relations\HasMany; 6use Illuminate\Foundation\Auth\User as Authenticatable; 7use Illuminate\Notifications\Notifiable; 8 9class User extends Authenticatable 10{ 11 use Notifiable; 12 13 /** 14 * The attributes that are mass assignable. 15 * 16 * @var array 17 */ 18 protected $fillable = [ 19 'name', 'email', 'password', 20 ]; 21 22 /** 23 * The attributes that should be hidden for arrays. 24 * 25 * @var array 26 */ 27 protected $hidden = [ 28 'password', 'remember_token', 29 ]; 30 31 /** 32 * The attributes that should be cast to native types. 33 * 34 * @var array 35 */ 36 protected $casts = [ 37 'email_verified_at' => 'datetime', 38 ]; 39 40 /** 41 * @return HasMany 42 */ 43 public function articles(): HasMany 44 { 45 return $this->hasMany(Article::class); 46 } 47}

controller

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Contracts\View\View; 6use Illuminate\Http\Request; 7 8class ArticleController extends Controller 9{ 10 /** 11 * Display a listing of the resource. 12 * 13 * @return View 14 */ 15 public function index(Request $request) 16 { 17 // ログインしているユーザーの投稿を全て取得 18 $articles = $request->user()->articles; 19 20 // 記事を投稿した日数を累計 21 $groupedArticlesByDateCount = $articles->groupBy('created_date')->count(); 22 23 return view('articles.index', compact('articles', 'groupedArticlesByDateCount')); 24 } 25}

投稿2021/05/24 06:05

phper.k

総合スコア3923

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

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

yuina711

2021/05/24 06:15

phper.k様 ご回答ありがとうございます。 提示していただきましたコードを参考に、再度コードの書き方等の基礎的な部分から見直したいと思います。 何度もやりとりしてくださり、本当にありがとうございました。
phper.k

2021/05/24 07:39 編集

> 再度コードの書き方等の基礎的な部分から見直したいと思います。 コードの書き方以前に、「Laravel の設計思想」を理解することの方が先ですね。 「Laravel の設計思想」を理解するには、MVCの基礎概念の理解が必要です。 https://ja.wikipedia.org/wiki/Model_View_Controller テイラーさんがいうには、Laravel は (厳密には)MVC ではないといいますが、MVCを理解していない人がLaravelを使っても、カオスになるだけ。
yuina711

2021/05/24 08:18 編集

学習の方向性までご教授してくださり、ありがとうございます。 下記リンク先を参考にしつつMVCを意識してコードを書いていたつもりなのですが、全く理解できていない自分に気づくことができました。もう一度、MVCの基礎概念を踏まえた上でLaravelの設計思想についても見直したいと思います。 https://zenn.dev/mpyw/articles/ce7d09eb6d8117 独学で学習していると、phper.k様のように間違い等を指摘してくださる方が周りにいないのでとても助かりました。本当にありがとうございました。
phper.k

2021/05/24 08:25

mpyw さんの記事は上級者向けの記事です。 Laravel が用意している基本機能をフル活用できた上で、さらに上の人が対象です。 あなたがやるべきことは、この「公式ドキュメントの日本語訳」を網羅して読むことですね。 https://readouble.com/laravel/6.x/ja/installation.html
yuina711

2021/05/24 08:34

ご返信頂きありがとうございます。 私は読むべき情報源を誤っていたのですね。 まずはドキュメントを繰り返し読むことから徹底したいと思います。 再度やるべきことをご教授してくださり、ありがとうございました。
guest

0

改善も何も全部間違ってるので
Laravelは投げ捨てて、PHPとデータベースとSQLの基礎から勉強しないと無理。

投稿2021/05/23 14:00

kawax

総合スコア10377

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

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

yuina711

2021/05/24 01:49

kawax様 ご指摘くださりありがとうございます。 再度勉強をやり直したいので、もし可能であればもう少し具体的に間違っている箇所を教えていただけると嬉しく思います。 よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問