toshizou-Rails

SQL問題(22/08/12)


表題

586. Customer Placing the Largest Number of Orders

自分の書いたコード

解答例(Discussから引用)



この問題から学んだこと

一番多い~~ の取得方法が一つ理解できた

1. group by で oo ごとにグループ分けして
2. order by count(oo) で集計して desc で降順に並べ替えて
3. limit 1 で1行のみに制限して
4. 必要な値を取得する
でできることがわかった。


以上

アルゴリズム問題(22/08/12)


今日は以下の問題を解きました。

問題

自分の書いたコード

使用したメソッド
解答例(Discussから引用)

この問題から学んだこと

stackという命名はわかりやすい

stackは日本語だと以下の意味になる。LIFO(Last In First Out)方式。
スタックとは何?わかりやすく解説 Weblio辞書

個人的には char_stackというのもありかなと感じた。

わからないこと

以下で取り上げられているMAPPINGというものがわからない
https://leetcode.com/problems/valid-parentheses/discuss/289504/Ruby-Solution


以上

SQL問題(22/08/06)


自分の書いたコード

I couldn't solve this.

解答例(Discussから引用)

この問題から学んだこと

個人的には解答例3が一番理解しやすい。

from句の後にテーブル名を複数指定できる

全く知りませんでした。
from句の後にテーブル名を複数指定すると「CROSS JOIN」で結合した場合と同じ結果が返ってくる。詳細は割愛、以下を参考にしています。
sqlでfrom句に複数テーブルを指定し、結合条件を記載しない場合の取得結果について

select文の結果をテーブルとして扱うことができる

select文を使用して抽出してきた結果を`as テーブル名`とすれば一つのテーブルとして扱うことができる。


以上

アルゴリズム問題(22/08/05)


自分の書いたコード

"I couldn't fix this"

解答例(Discussから引用)

この問題から学んだこと

設問の意味を正しく理解すること

Longest Common Prefix の意味を勘違いしていた。

o 文字の先頭から共通する文字
x 文字のいずれかの位置から共通する文字

これからもこのような間違いが起きるのは避けられないので、前違えた場合は意図していることをちゃんと理解しないと大変なことになる。

String#rangeは2つの意味がある場合がある(?)

String#[] (Ruby 3.1 リファレンスマニュアル)


上記が参考になりました。
String[a...b]のaとbの間の点の数で、意味合いが違う。
点2つ: rangeオブジェクトが終端を含む場合。インデックスと文字列を対応させる
点3つ: rangeオブジェクトが終端を含まない場合。文字列と「隙間」を対応させる


以上

SQL問題(22/08/05)


自分の書いたコード

以下は参考にしたリンク
MySQL | データをグループ化する(GROUP BY句)
SQLで同一グループの中で最大/最小のレコードを取得する - Qiita

解答的にはok。

SELECT player_id, min(event_date) AS first_login FROM Activity
GROUP BY player_id

でもパフォーマンスが悪いように感じる...

Runtime: 1289 ms, faster than 7.13% of MySQL online submissions for Game Play Analysis I.
Memory Usage: 0B, less than 100.00% of MySQL online submissions for Game Play Analysis I.

答え(Discussから引用)



この問題から学んだこと

DISTINCTは高速化につながる(?)

DISTINCTの使い方及び、GROUP BYとの違いについて | IT職種コラム
SQL distinctとgroup byの実行計画が全く同じなのに大きな速度差が出る | ポテパンスタイル
DISTINCT vs GROUP BY - BASEプロダクトチームブログ

上記が参考になりました。

DISTINCTは、重複を排除した結果を出力する場合に使用
GROUP BYは、重複を排除した結果に対して集計処理を行いたい場合に使用

といった感じに使うのが良さそうらしい。

ただ、joinする場合は状況によって distinct, exists, group by のどれが早いかはある程度の件数のテストデータを使ってレスポンスの違いを観察する必要があるらしい。


以上

SQL問題(22/08/04)


問題リンク

Loading...

自分の書いたコード

SELECT name FROM Customers
INNER JOIN Orders
ON Customers.id = Orders.customerId

答え(Discussから引用)



この問題から学んだこと

LeetCodeのSQL問題ではheaders情報にはテーブル名が出力されるようにする

たいていは AS句 を使用してテーブル名を出力させればok(?)

NULLを使用して条件を絞り込める

JOINとLEFT JOINの違いをきちんと理解する - 箱のプログラミング日記。
上記が参考になりました。

  • JOINの場合、合致する右表のレコードがない場合は対応する左表のレコードが削除される(結果に出力されない)
  • LEFT JOINの場合、合致する右表のレコードがない場合でも対応する左表のレコードが残る(結合条件のカラムはNULLの状態で出力される)

今回の問題は以下を理解すれば解けることになります。

  • LEFT JOIN, ON, WHERE, IS NULL を使用する
  • 右表(Orders)のデータがNULLであることを利用する
NOT INを使用して簡潔にも書ける

そのまま文言を転用させていただきます。

一言でその機能を説明するなら「指定した要素を含んでいないレコード(行)を取得する」と言ったところでしょうか。

【SQL】NOT INの使い方!基本からよくある問題まで! | 侍エンジニアブログ



以上

22/1/31 ~ 22/2/6の進捗

今週の計画

今週計画したことは以下の通り。

  • 新アプリの開発(Firebase Authenticationを使用して新規ユーザーの登録、ログイン機能を実装する)
  • メンターのアプリ開発の手伝い

今週やったこと

アプリの開発(Firebase Authenticationを使用して新規ユーザーの登録、ログイン機能を実装する)

実装できていないが、すこしずつ全体像が見えてきた。
今週中には完了したい。

今週初めて知ったこと

定数の設定(置き場所)は複数の選択肢がある

2個ぐらい選択肢があるのかなと思ったらもっとあったのでメモ。
Ruby on Railsで定数の指定 - Qiita

  • ApplicationControllerに書く
  • config/initializers/constants.rbで宣言
  • SettingsLogic
  • gem config <- これが主流らしい
  • Railsデフォルトのconfig <- これには難があるらしい。

上記リンクでは取り上げられていませんが

  • lib/app_constants.rbを作成して定数を記述する

方法もあるみたい。

ホントに書き方まちまちですね...
Railsでの定数定義 - rochefort's blog


ちなみにRailsガイドにも定数が少し取り上げられていますが、書き方に関する内容は薄めでした。
定数の自動読み込みと再読み込み - Railsガイド




以上。

22/1/24 ~ 22/1/30の進捗

今週の計画

今週計画したことは以下の通り。

  • 新アプリの開発(Firebase Authenticationを使用して新規ユーザーの登録、ログイン機能を実装する)
  • メンターのアプリ開発の手伝い(SlackAPIとActiveJobを使用した昨日の実装)

今週やったこと

アプリの開発(Firebase Authenticationを使用して新規ユーザーの登録、ログイン機能を実装する)

まだ実装できていない。
下記でも述べているが`publicRuntimeConfig`を使用して実装する方法ができていない。

SlackAPIとActiveJobを使用した機能の実装

先週に続いて続行。
エラーなどの微調整が終了しました。

今週初めて知ったこと

`@nuxtjs/dotenv`が非推奨だった

いろいろと調べているとNuxt2では`@nuxtjs/dotenv`が非推奨になり代わりに`publicRuntimeConfig`を使用することが推奨されていました。
ただそれに関して実装した方法の記事が少なく`$config`を使用した実装方法に困っている状態です。


以上。

今週の進捗(22/1/17 ~ /22/1/23)

今週の計画

今週計画したことは以下の通り。

  • 旧アプリをAWSからHerokuへ移行
  • 新アプリの開発(Rails x Nuxt.js環境の構築, )
  • メンターのアプリ開発の手伝い(SlackAPIとActiveJobを使用した昨日の実装)

今週やったこと

旧アプリをAWSからHerokuへ移行

参考になるサイトが比較的速く見つかったのですぐ終わるかと思ったが、微妙に違ったりして本当に予想外に時間がかかってしまった。
完了するのに3日以上もかかってしまった...。

新アプリの開発

以前作成したアプリがあまりにも使いづらいとのことだったので全く別の小さなアプリをポートフォリオとして作成することにした。
ただ作成というよりも計画立案、環境構築で終わった。

  • Rails側の設定
    • Rubocopの設定
    • RSpecの設定
  • Rails + Nuxt.js の連携確認

Rubocop・RSpectの設定、Rails + Nuxt.js の連携確認は1日ずつかかってしまったがなんとかできた。

SlackAPIとActiveJobを使用した機能の実装

現在のRailsアプリで登録画面からワークスペースへのSlackユーザーの登録ができるようになっている。
それにプラスして以下の実装を行なっている。

  • SlackAPIを使用してユーザーが登録されたタイミングで参加必須のチャンネルに参加させる

まだ完成はしていないので、できるだけ早めに終わるようにしたい。

今週初めて知ったこと

ActiveJobのログの確認方法

ActiveJobに関しては旧アプリのメール送信で使ったことがあるが、その時は特にエラーもなくすぐに実装できた。

ただ今回に関しては参考になるサイトなども少なく、手探りでやっていたため、エラーの内容を知りたかった。
それを調べていたが、まったくわからなかった(Railsガイドで`development`、`ログ`、`デバッグ`というキーワードで探してもわからなかった Active Job の基礎 - Railsガイド)。
アドバイスをもらうと`log/development.log`に表示されていることを教えてもらった。
確かにログが残っている。

まだ実装が完了していないので終わったら記録しておく。

環境変数 ≠ 秘匿情報

以前はAWSやHerokuへデプロイするときなどに`rails-dotenv`なるgemを使っていたが、どの記事でも`環境変数`というワードがキーワードになっていた。

そのため APIに使用するためのキーなどは全て環境変数という認識だった(そもそも秘匿情報という言葉を使うことが思い浮かばなかったので知識がそこまで達していない?)。
以下のように覚えておけばよさそう。

  • 環境変数はアプリ以外にも様々な設定に使用する変数
  • 秘匿情報は外部の人に知られるとマズい情報(APIのproduction用のキーとか他人が悪用して被害をこうむる)

無料で制限がない or テスト用のAPIキーなどなら秘匿せずにそのまま直打ちしてGitHubにpushしても問題ないらしい。
アドバイスありがとうございます。

P.S
`activejob ログ 確認`でググったらクラスメソッドさんの記事が出てきた。これだw
やっぱり検索キーワードは大事だ。
[Ruby on Rails]Active Job – Sidekiqを使ってのJobの実行 | DevelopersIO


以上。

今週の進捗

今週の計画

今週計画したことは以下の通り。

  • 新アプリの作成
  • 求人に対する応募
  • メンターのアプリ開発の手伝い(?)

今週やったこと

新アプリの作成

以前作成したアプリがあまりにも使いづらいとのことだったので全く別の小さなアプリをポートフォリオとして作成することにした。
ただ作成というよりも計画立案、環境構築で終わった。

特にRails x MySQL8の環境構築に1日以上取られてしまった...

今週初めて知ったこと

alipine Linux

Dockerを使用する時にalpineLinuxを使用している例はよく見かける。
でもどうやってみんなalpineLinuxのパッケージを探しているんだろうと気になっていた。
たまたま

alpine nodejs unable to select packages

というエラーに遭遇して調べていると、ERROR: unable to select packages error on Alpine Linux - Hasan Altinの記事のリンクからalpineLinuxのパッケージを検索できることを知った。
地味に嬉しいw

推測を求められたら推測だけでなくその根拠も伝えるということ

レビュワーからアドバイスをもらう時にときどき言われて後から気づくことがあるので依頼前のチェックリストの備忘録として残します。

結論(今回学んだこと、今後のチェックリスト)

  • 自分なりの推測を求められたら引用できる内容(ネット記事やコードなど)を添えて根拠を伝える
  • 思い込みによる推論をしない <- 思い込みによる推論が正しいか(根拠があっているか)ネットで調べる
  • 質問する必要が出てきた時にissueを再確認する(質問する内容とissueの内容が完全に合致しているか確認する)
自分なりの推測を求められたら引用できる内容(ネット記事やコードなど)を添えて根拠を伝える

分からない時は プログラミングの正しい質問方法をプロが体系的に解説 | 侍エンジニアブログ の`3つの質問テンプレート`を参考にしてつくるのが良さそう。

今回は`「どこが原因だと思いますか?」`とレビュワーに質問されました。

レビュワーの意図は `確認すべきファイル、処理は妥当なところか?`ということが知りたかったのだと思います。
今回は見るべき部分を見ていたので問題はなく良かったです。
以前は自分の乏しい経験則や勘で`ここらへんだと思う`というざっくりとした返答しかできなかった時期があり、その


思い込みによる推論をしない <- 思い込みによる推論が正しいか(根拠があっているか)ネットで調べる

今回は自分の思い込みが原因で修正すべき箇所を見つけることができませんでした。
複数レコードを取得してくる際はレコードのidを基準に整理されて格納されると思っていました。
通常複数レコードを取得して表示する場合はorderを指定する必要があるのですが、それを失念していました。
mysql - ORDER BY を指定しない時 / SELECT結果表示並び順 の法則性 - スタック・オーバーフロー

なかなか自分で気づくのは難しいですが、本当にダメな場合は自分の考えている前提が正しいのか確認したほうが良いと感じました。

雑感

少しずつコードを読むことはできるようになってきている気はするが、

  • コードをすぐ理解できrこと
  • 原因箇所を特定すること
  • 特定して修正すること

の能力が着実に上がって欲しいな...とおもいましたw


P.S.
そもそも論としてissueを誤解釈していたことが始まりだったように思います。
issueをしっかりと確認すれば解決できる内容だったかもしれません...

PRを発行してコードをレビュー(質問に解答)していただいた時にアドバイスされたこと

コードをレビューしていただく機会がありその内容を忘れないために備忘録として残しておきます。

使用しているサイト・ツール

qiitaで以下の素晴らしい記事を見つけました。
qiita.com

今回はそれとは別に自分がアドバイスいただいた内容を列挙します。

【その前に1】PRを作成するときに必要なこと

先述したqiitaの該当箇所がわかりやすくとても丁寧です。
リンクを貼っておきます。
https://qiita.com/hinora/items/fb083a97d6e2ab8a9aa3#--%E3%83%97%E3%83%AB%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88
項目としては大きく4つで

  1. 概要
  2. issue またはチケットへの関連づけ
  3. 画像を
  4. コミュニケーション

に大きく分類されるそうです。

教えていただいたこと

アサインされた機能を実装できずに困っていたらPRに詳細を書く

最初はどうしても実装できずに困ってSlackでやりとりして質問していました。
アドバイスいただいた方も仕事をされており、かなり忙しいので効率的に問題解決しようと

どうしても自分で解決できなかった場合はGitHubでPRを作成して具体的にどう詰まっているかをそこに書いてください。

とアドバイスしていただきました。

1 のところはてっきり困っている内容を書いてはいけないと思っていました。
人によって賛否はあるかもしれませんがこの手法を取り入れてからアドバイスいただく方とのやりとりがスムーズになりました。

また最近になって気づきましたがレビューしていただく方も忙しいので以下を参考に作成することを心がけていきたいと思います。
www.sejuku.net

Markdownに画像を貼る(Gyazo)

PRを作成した時に、実装できた証明としてスクショが欲しいと言われました。
つい最近までmacスクリーンショット 機能を使用していましたが、

Gyazoがあるのでそれを使ってみましょう

と言われ、このときに初めてGyazoの存在を知りました。
リンクを載せておけばよいと勝手に誤解釈してしまっていたのですが、それではダメでリンクを使用して表示する方法を使ってくださいとのことでした。
やり方を教えていただいた後に

gyazo 画像 表示 - Google 検索

で調べてみるとあるじゃありませんか、わかりやすい記事が...
以降は以下の記事を参考にして効率的に画像リンクを作成しています。
webrandum.net

特殊文字(@)を使用する場合は``で囲む

現在Railsポートフォリオを作成しています。
Railsではインスタンスの宣言をするときに(@)をします。
コメントのやりとりでアドバイスいただいた方と幾度かやりとりしていると、なんと別の国のGitHubユーザーから

関係ないおれにメンションしてこないでくれ

と連絡が来たそうです(どうやって連絡が来たのかはしりません...)。

GitHub(or slack)でメンションが必要ない場合``で囲んだほうがよいようです。

雑感

個人開発しているとわからないこと、知らないことがあることを改めて実感しました。

P.S.
あと5日で2022年に突入...
よいお年をw

Rails5以降になって表示された警告

警告が出て毎回焦るのは嫌なので備忘録としてメモ。

 

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (xxx KiB). This can impact web performance.
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (xxx KiB). This can impact web performance.
WARNING in webpack performance recommendations:
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application

上の三つの文言は全てwebpack関連の警告です。

rake asset:precompile コマンドを実行した最後の方にログとして表示されました。

上から順に翻訳すると下記のようになります。

  • アセットサイズ制限の警告:次のアセットは、推奨サイズ制限(xxx KiB)を超えています。 これはWebのパフォーマンスに影響を与える可能性があります。
  • エントリポイントサイズ制限の警告:次のエントリポイントの合計アセットサイズが推奨制限(xxx KiB)を超えています。 これはWebのパフォーマンスに影響を与える可能性があります。
  • webpackのパフォーマンスに関する推奨事項の警告:
    import()またはrequire.ensureを使用してバンドルのサイズを制限し、アプリケーションの一部を遅延ロードすることができます。

解決法はまだ探せていないのでわかったら後で追記します。

MojaveでアプリがインストールできなかったのCatalinaにバージョンアップした

現職の仕事や諸事情でPCに全く触れてませんでした(m_ _m)

今日からゆっくり、ぽつぽつ、ちびちびと書いていきます。

 

tl;dr

最新のOSバージョンから1つ下のがベターなのかも...

 

普段はMojaveを使ってました

私が普段使っているPCは

MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)

です。

 

 久しぶりに使い始める前にMojaveOS用のアップデートがあったので実行しました。

そのあとから劇的に下記のような不具合が頻発するようになりました。

  • かなりの頻度でインターネット(Wifi)につながらない(有線では確認していない)
  • AppStoreのアプリをアップデート、ダウンロードできない

 

正直まともに使えたものではありません。

再起動、セーフブート、SMCリセットを試してみましたが改善しませんでした。

 

バックアップはとってあるので初期化も検討しましたが、

以前初期化した時に

不可視ファイルがなくなってしまって、一から設定をし直すハメになった

ので今回は初期化しない方向でやりたいと思いました。

 

サポートセンター に問い合わせてみた

インターネットにつながらないのは致命的なのでサポートセンター に問い合わせたところ、上記でも取り上げた

  • セーフブート
  • バックアップをとって、初期化する

といった内容でした。

初期化は絶対にしたくなかったので、仕方なくCatalinaへアップグレードすることに。

Catalinaへのアップグレードは無事終わり、とりあえずほぼ問題なく使えています。

 

ただし、

ブラウザからAppStore登録のアプリ詳細画面へ遷移するとアクセスする権限がありませんと相変わらず怒られます...

いつからだったかは覚えてませんが、この画面が表示されるようになってからしばらく経ちます。

いろいろ調べてみたり、サポートセンターでも聞いてみましたが、問題は解決せず(m_ _m)

だれか知ってる人いたら教えて欲しいですね、笑。

RSpecで発生したエラーめも(随時追加予定)

この記事でやること

RSpecで発生したエラーとその解決方法を

開発環境

RequestSpecでのエラー

ArgumentError: x is not a valid column_name
# app/models/cuisine.rb
class Cuisine < ApplicationRecord
  enum difficulty: { easy: 0, normal: 1, hard: 2 }
  has_many :foodstuffs, dependent: :destroy
end

# spec/factories/cuisines.rb
FactoryBot.define do
  factory :cuisine do
    sequence(:name) {|n| "料理名#{n}" }
    # before(NG):
    #  この状態だと enum の value を返す
    sequence(:difficulty) {|n| n }
    # after(OK):
    #  ・keyを取得するように設定
    #  ・Cuisine.difficulties.keys で enumの値を全て取得して
    #   sampleメソッドでそのうちのどれかを返す
    difficulty { Cuisine.difficulties.keys.sample }
  end
end