- 投稿日:2020-12-06T23:10:51+09:00
第10回
フィボナッチ数列を再帰で求める
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 …のように第n項 + 第n+1項 = 第n+2項となるのがフィボナッチ数列.
再帰メソッドって?
メソッド内で自分自身を呼び出すメソッドのこと.メリットとしてコードが簡潔になる.漸化式の要領と似ているかもしれない.
とりあえず第1項と第2項
フィボナッチ数列の第1項と第2項はそれぞれ0, 1と計算では求められないので定義しておく.出力の確認には前回のメソッドassert_equalを使う.
require './assert_equal' def fib(n) if n == 0 return 0 end if n == 1 return 1 end end puts assert_equal(0, fib(0)) puts assert_equal(1, fib(1))リファクタリング!!
出力確認の部分,
puts assert_equal(0, fib(0)) puts assert_equal(1, fib(1))は後々増える可能性があるので,配列にしてループを回すことでコードをわかりやすくする.
test =[[0, 0], [1, 1]] test.each do |index, expected| puts assert_equal(expected, fib(index)) endこのようにプログラムの挙動を変えずに内部構造を整理することをリファクタリングと言う.
第3項以降
前述の通り,フィボナッチ数列は第n項 + 第n+1項 = 第n+2項であるので,fib(n+2) = fib(n) + fib(n+1)で求められる.
require './assert_equal' def fib(n) if n == 0 return 0 end if n == 1 return 1 end return fib(n - 1) + fib(n - 2) end test =[[0, 0], [1, 1],[8, 21]] test.each do |index, expected| puts assert_equal(expected, fib(index)) endもっと見やすくする
rubyはこんな形でも値を帰すことができる.
return 0 if n == 0 return 1 if n == 1これに従って書き換えると,
require './assert_equal' def fib(n) return 0 if n == 0 return 1 if n == 1 return fib(n-1) + fib(n-2) end test =[[0, 0], [1, 1],[8, 21]] test.each do |index, expected| puts assert_equal(expected, fib(index)) endとより見やすく可読性を高くすることができた.
参考サイト
この記事は以下のサイトを参考に作成しました.
- source ~/grad_members_20f/members/musutafakemaru/10.org
- 投稿日:2020-12-06T22:54:08+09:00
Ruby の Hash における keys.each と each_key の違い
はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。今回のお題
AtCoder Typical DP Contest A - コンテスト
Difficulty: ---今回のテーマ、動的計画法
問題自体は
動的計画法の基本だと思われます。Hash#keys
ruby.rbgets p = gets.split.map(&:to_i) dp = Hash.new(0) dp[0] = 1 p.each do |x| dp.keys.each do |y| dp[x + y] = 1 end end puts dp.sizeやっていることは、@kakudaisuke さんの AtCoder Typical DP ContestのA - コンテストを絵で理解してみたい(PHP) の通りです。
Hash#each_key --失敗--
ruby.rbgets p = gets.split.map(&:to_i) dp = Hash.new(0) dp[0] = 1 p.each do |x| dp.each_key do |y| dp[x + y] = 1 end end puts dp.sizeerror.rbcan't add a new key into hash during iteration (RuntimeError)反復中にハッシュに新しいキーを追加できません
ああ、似ているけどkeys.eachとeach_keyは違うのですね。Array コピー
ruby.rbgets p = gets.split.map(&:to_i) dp = Array.new(p.sum.next, 0) dp[0] = 1 p.each do |x| dp_tmp = dp.dup dp.each_index do |i| next if dp[i].zero? dp_tmp[x + i] = 1 end dp = dp_tmp end puts dp.count(1)配列の場合、代入はできるのですが、正解を得るには
clone又はdupにて配列をコピーする必要があります。Array 後ろから
ruby.rbgets p = gets.split.map(&:to_i) dp = Array.new(p.sum.next, 0) dp[0] = 1 p.each do |x| p.sum.downto(0) do |i| next if dp[i].zero? dp[x + i] = 1 end end puts dp.count(1)
downtoやeach_indexを使用し、後ろから探索すると、配列のコピーが不要となります。まとめ
- Typical DP A を解いた
- Ruby に詳しくなった
- 投稿日:2020-12-06T20:45:56+09:00
【Ruby】コントローラーでメソッドによるコード省略
読んでなるほど!と思うのに、しばらくするとなんだっけ?ってなるシリーズその1
・edit
・show
この2つのアクションの記述をぎゅっとコンパクトに。使用するのは、
before_action
onlyオプションtweets_controller.rbclass TweetsController < ApplicationController def edit @tweet = Tweet.find(params[:id]) end #↑editの中身「@tweet = Tweet.find(params[:id])」と、 #↓showの中身が同一の記述になっている def show @tweet = Tweet.find(params[:id]) end private end重複している部分を「set_tweet」として、privateメソッドに移し替える
tweets_controller.rbprivate def set_tweet @tweet = Tweet.find(params[:id]) endbefore_actionの記述方法
tweets_controller.rbbefore_action :処理させたいメソッド名 before_action :set_tweet, only: [:edit, :show]最後にまとめると
tweets_controller.rbclass TweetsController < ApplicationController before_action :set_tweet, only: [:edit, :show] def edit end def show end private def set_tweet @tweet = Tweet.find(params[:id]) end endeditとshowに入っていた
@tweet = Tweet.find(params[:id])
これをset_tweetとインスタンスで定義。
そして一番上で
:set_tweet, only: [:edit, :show]
としてeditとshowのみに使うようonlyオプションで指定
- 投稿日:2020-12-06T20:43:03+09:00
【Rails】プログラミング初心者が大学生の悩みを解決するアプリに付けた機能一覧
1. はじめに
少し前に大学生の悩みを聞く機会があったのですが、そこで多くの大学生が「課題が多すぎる」という悩みを抱えていることを知りました。〆切を守れないことから自己嫌悪に陥ってしまう学生を目の当たりにすることもありました。
特に最近はこんなご時世ですから、通常の授業がオンライン授業に切り替わり、教員は学生の出席状況を小まめにチェックしたり、学生にテストを課したりすることができない分、レポート課題などを出すという流れに変わってきています。その結果、ますます多くの課題に頭を抱える大学生が増えているというわけです。
というわけで、「課題の多さに悩む大学生を何とかして助けたい」という思いが生まれ、その思いをもとにオリジナルアプリを作ることにしました。
そうは言っても、課題そのものを減らすことはできないので、できるだけ楽しく課題に取り組めるような仕組みを作るという方向性でアイデアを出していきました。
そして誕生したのが 『〆KiList』 です。
Illustrated by Strories by Freepik
2. 「課題が多すぎる」という悩みを深掘る
1. はじめにで説明した通り、〆KiListを作成した目的は課題の多さに悩む大学生を助けるためでした。この目的を達成するためには、まず「課題が多すぎる」という悩みが表す意味をさらに深掘って考える必要がありました。
私は「課題が多すぎる」という悩みの根源は、以下の2点ではないかと考えました。
課題に取り組むモチベーションがわかない
課題のスケジュール管理が難しい
よって、大学生の「課題が多すぎる」悩みを解決するためには、以下の2つの仕組みを作る必要があると考えました。
課題に取り組むモチベーションが上がる仕組み
課題のスケジュール管理をしやすくする仕組み
3. 機能一覧
〆KiListに付けた全ての機能は以下の18機能です。
機能 Gem ① ログイン機能 devise ② ToDoリスト機能(CRUD) × ③ カレンダー機能 FullCalendar ④ いいね機能(Ajax) × ⑤ コメント機能(Ajax) × ⑥ フォロー機能 × ⑦ 宣言機能 ⑧ わたしも機能(勝手に命名) × ⑨ つぶやき機能(CRUD) × ⑩ 検索機能 ransack ⑪ ページネーション機能 kaminari ⑫ グラフ機能(ドーナツチャート) Chartkick ⑬ レベル表示機能 × ⑭ ランキング機能 × ⑮ 付箋機能(勝手に命名) × ⑯ 画像アップロード機能 CarrierWave ⑰ 簡単ログイン機能 × ⑱ 管理者機能 × この中でも、「課題が多すぎる」という悩みを解決するのに必要な2つの仕組みを実現するために付けた機能は、② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑫ ⑬ ⑭ ⑮の12機能です。
機能 Gem ② ToDoリスト機能(CRUD) × ③ カレンダー機能 FullCalendar ④ いいね機能(Ajax) × ⑤ コメント機能(Ajax) × ⑥ フォロー機能 × ⑦ 宣言機能 × ⑧ わたしも機能(勝手に命名) × ⑨ つぶやき機能(CRUD) × ⑫ グラフ機能(ドーナツチャート) Chartkick ⑬ レベル表示機能 × ⑭ ランキング機能 × ⑮ 付箋機能(勝手に命名) × これらの機能の概要と2つの仕組み実現のために工夫した点・思いについて、ここから1機能ずつ解説したいと思います!
4. 機能の解説
ToDoリスト機能
概要
ToDoリスト機能です。使い方は、とてもシンプルです。①課題を登録
②課題がリスト化される
③完了ボタンを押すと完了済みに入る(完了済みから戻すのもできます!)
工夫した点①シンプル
まずはシンプルを心がけました。アプリ名にもなっているメイン部分ではありますが、色々機能があっても使いにくいと思ったのでここはシンプルに課題名と〆切日だけを表示させました。②リマインド
「〆切をうっかり忘れていた」というようなことを防ぐために〆切1日前、〆切当日、〆切が過ぎている課題のリマインド機能を付けました。
また、〆切が過ぎている課題にはリストに赤い砂時計が表示されるようにしました。③実施日の登録
課題登録時に、〆切の何日前にするかという課題実施日も登録してもらうようにしました。これは、課題を「いつやるか」を考える習慣を付けることは、スケジュール管理が得意になる上で重要だと考えているためです。この仕組みを利用してその習慣を身に付けてもらえたらいいなという思いを込めて付けました。カレンダー機能
概要
〆切を可視化できるカレンダーです。課題を登録すると、自動で〆切日のみ表示されるようになります。終わった課題は表示されません。それぞれの課題をクリックすると詳細画面に飛びます。
工夫した点
①シンプル
リスト機能と同じくこちらもシンプルを心がけました。
〆切日のみに絞ってカレンダーに表示させることで、〆切日がひと目で分かるようにしました。②〆切のカラー
通常は緑色のラベルで課題が表示されますが、〆切が過ぎている課題は赤でラベルが表示されます。パッと見て、「いますぐやるべき課題」が分かります。いいね・コメント・フォロー
概要
SNSにはお馴染みの3機能です。
工夫した点これらの機能自体に特別な工夫があるわけではないですが、SNSやっている人なら誰もが一度は味わったことのある「いいねやコメントをもらう喜び」「誰かにフォローされる喜び」を〆KiListユーザーにも味わってもらい、課題に取り組む際のモチベーションにしてもらいたいなという思いを込めて実装しました。
宣言機能(オリジナル)
概要
課題を登録した際に、宣言ボタンが表示されます。
押すと、「いつ何の課題をするか」をみんなのつぶやき一覧に投稿できます。
工夫した点
①手間いらず
無駄な行程を踏まずに済むように、文章を自分で入れなくても、ボタン1つですぐに宣言できるようにしました。②やらざるを得ない環境の仕組み化
みんなの前で宣言して、やらざるを得ない状況を作る仕組みを仕掛けました。自分で管理するだけではついつい「明日でいっか」ってなってしまいますが、他の人に宣言しちゃうと何かやらなきゃいけない気がしてくると思います。その効果を利用しました。わたしも機能(オリジナル)
概要
挙手のマークを押すと、他の人が宣言している課題を、自分の〆KiListにも登録できます。挙手のマークは、自分以外の他のユーザーの課題宣言の投稿にのみ表示されています。主に同じ大学、学部の人とかが使いやすい機能かと思います。
工夫した点
①手間いらず
他の人の宣言を見て、「あ、この課題自分もやらなきゃいけなかった!」と思った時に、余計な行程を辿らず、すぐに課題が登録できるようにと思い、この機能を付けました。②仲間意識・ライバル意識を活用
「友達がやるなら、自分も一緒に頑張ろう」という仲間意識や「あいつに負けないように自分も頑張らないと」というライバル意識をモチベーションにする方は結構多いと思います。そういう人たちに、積極的に課題を登録してもらえるようにと思い、この仕組みを仕掛けました。つぶやき機能
工夫した点
・ToDoリスト×SNS
孤独な環境だと、どうしても課題が進められない人は多いと思います。そこで、つぶやき機能(SNS的な要素)を使って他の学生と積極的にコミュニケーションを取りながら、みんなで課題に取り組める仕組みを作りたいと思い、実装しました。グラフ機能(ドーナツチャート)
概要
課題達成率(今まで登録した課題のうち、達成済みの課題数の割合)、〆切遵守率(達成した課題数のうち、〆切を守った課題数の割合)がドーナツチャートでグラフ化されます。課題を完了すると、〆切達成率・〆切順守率が変わっていることが分かります。
工夫した点
①課題に取り組む姿勢を数値化・可視化
努力を数字やグラフで可視化させ、モチベーション維持に繋げてくれたらいいなと思い、実装しました。②人に見られる環境の仕組み化
グラフはマイページに表示されています。そのページに飛んでくれば、自分の課題に取り組む姿勢が他の人の目に触れることになります。人に自分の努力値が見られている環境に置かれていることもまた頑張るモチベーションになるかなと思い、この機能を付けました。レベル表示機能
概要
課題の完了数が増えていくにつれてレベルが上がっていきます。
「ビギナー」「中級者」などクラスも表示されます。
レベルが高ければ高いほど、課題をしっかりと完了させているという証明になります。
工夫した点
①次のクラスを目指すワクワク感
ユーザーが「次はどんなクラスかな?」「私も〇〇クラス目指して頑張ろ!」と楽しめるようにして、頑張れるモチベーションにしてもらえたらなと思い、実装しました。
この辺のバリエーションはまだまだ増やす余地ありなので、さらに色々なクラスを用意して、ユーザーにワクワクしてもらえるような仕様にしていきたいと考えています。②遊び心
真面目すぎるアプリは、少し使うとすぐに飽きてしまいます。なので、所々遊び心を加えて、ユーザーに楽しんでもらいながら長く使ってもらえるようにと思い、「何やコレ」と言うようなクラスを用意しました。例えば、Lv.1のクラスは「赤ちゃん」です。かわいいですね。育てたくなりますね。
ランキング機能
概要
レベルが上位3名になると、ランキングにユーザー名とレベルが載ります。
工夫した点
・ランキングに載ることへのモチベーション
ランキングに載ることもまた、一種のモチベーションになると思います。
「ランキングに名前を載せるために課題を頑張ろう!」と思ってもらえるようにこの機能を付けました。
ただし、今のところ見ての通りあまりにもデザインがシンプル過ぎて、名前が載っても「何だかな〜」と言う感じなので、もう少しモチベーション上がるような見栄えを目指したところです。付箋機能
概要
登録した課題と〆切日が、付箋のような感じで表示されます。本日〆切、本日実施の課題もすぐに分かります。
ここから課題の詳細ページに飛ぶこともできます。
工夫した点
・アプリ使用中は〆切を意識
このアプリは、課題の〆切日を守るためのアプリなので、常に〆切を意識してもらう必要があります。通常であれば、〆KiListのページに行かないと〆切を見ることができないことになってしまいますが、この付箋機能をマイページとつぶやき一覧ページに載せることで、アプリを使っている最中は常に〆切を意識してもらえることになります。〆切のうっかり忘れの防止をさらに強化するために、この機能を実装しました。番外編:〆KiListの色について
今回〆KiListを作成するにあたって、カラーを下記の通り選択しました。
- メインカラー:ネイビー、オレンジ、ホワイト
- サブカラー:グレー、ブルー(ボタンにカーソル置いた時)
基本的には、メインカラーを使うように気をつけました。
自分はデザイン的な知識は全くないので、色で統一感を出すことでそれなりにまとまりのある感じを出そうという発想になり、その結果使う色を3色に絞りました。ただし、全部がこの色だと面白味がないので、ボタンにカーソルをのせた時やちょっとしたデザインの部分に関しては、グレーやブルーなど、メインカラーに比較的馴染みが良いであろうカラーを使うようにしました。
(カレンダーは土曜日のイメージが青や水色、日曜日のイメージが赤やピンクなので例外です)尚、一番のメインカラーはネイビーですが、これは青系の色の方が、「勉強」「課題」といった真面目な印象を与えやすいから選択しました。
そこにオレンジという暖色を加えたのは、〆KiListがSNS的な要素を持ち、「人との繋がり」「励まし合い」といった要素も含むからです。
ネイビー×オレンジという組み合わせが結構しっくりきたのでこれらの色をメインに使いました。
さいごに
長くなりましたが、以上です。
大学生の「課題が多すぎる」という悩みを解決するためには、
①課題に取り組むモチベーションが上がる仕組み
②課題のスケジュール管理をしやすくする仕組みこの2つの仕組みが必要で、この仕組みを実現するために、今回解説した12機能を付けたというお話でした。
ここまで読んでいただいてありがとうございます。予定
①この記事は、今のところ「思い」の部分が前面に出た記事になっておりますので、今後はそれぞれの機能についてどのように実装したかという技術的な部分も付け加えていけたらと思っています。
②今回は、機能という部分に着目しましたが、ポートフォリオ(このアプリ)の作成の全体的な解説記事は別で投稿します。それまでにAWSでのデプロイを頑張ります。
- 投稿日:2020-12-06T20:43:03+09:00
【Rails】プログラミング初心者が大学生の悩みを解決するアプリに付けた12機能
1. はじめに
少し前に大学生の悩みを聞く機会があったのですが、そこで多くの大学生が「課題が多すぎる」という悩みを抱えていることを知りました。〆切を守れないことから自己嫌悪に陥ってしまう学生を目の当たりにすることもありました。
特に最近はこんなご時世ですから、通常の授業がオンライン授業に切り替わり、教員は学生の出席状況を小まめにチェックしたり、学生にテストを課したりすることができない分、レポート課題などを出すという流れに変わってきています。その結果、ますます多くの課題に頭を抱える大学生が増えているというわけです。
というわけで、「課題の多さに悩む大学生を何とかして助けたい」という思いが生まれ、その思いをもとにオリジナルアプリを作ることにしました。
そうは言っても、課題そのものを減らすことはできないので、できるだけ楽しく課題に取り組めるような仕組みを作るという方向性でアイデアを出していきました。
そして誕生したのが 『〆KiList』 です。
Illustrated by Strories by Freepik
2. 「課題が多すぎる」という悩みを深掘る
1. はじめにで説明した通り、〆KiListを作成した目的は課題の多さに悩む大学生を助けるためでした。この目的を達成するためには、まず「課題が多すぎる」という悩みが表す意味をさらに深掘って考える必要がありました。
私は「課題が多すぎる」という悩みの根源は、以下の2点ではないかと考えました。
課題に取り組むモチベーションがわかない
課題のスケジュール管理が難しい
よって、大学生の「課題が多すぎる」悩みを解決するためには、以下の2つの仕組みを作る必要があると考えました。
課題に取り組むモチベーションが上がる仕組み
課題のスケジュール管理をしやすくする仕組み
3. 機能一覧
〆KiListに付けた全ての機能は以下の18機能です。
機能 Gem ① ログイン機能 devise ② ToDoリスト機能(CRUD) × ③ カレンダー機能 FullCalendar ④ いいね機能(Ajax) × ⑤ コメント機能(Ajax) × ⑥ フォロー機能 × ⑦ 宣言機能 ⑧ わたしも機能(勝手に命名) × ⑨ つぶやき機能(CRUD) × ⑩ 検索機能 ransack ⑪ ページネーション機能 kaminari ⑫ グラフ機能(ドーナツチャート) Chartkick ⑬ レベル表示機能 × ⑭ ランキング機能 × ⑮ 付箋機能(勝手に命名) × ⑯ 画像アップロード機能 CarrierWave ⑰ 簡単ログイン機能 × ⑱ 管理者機能 × この中でも、「課題が多すぎる」という悩みを解決するのに必要な2つの仕組みを実現するために付けた機能は、② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑫ ⑬ ⑭ ⑮の12機能です。
機能 Gem ② ToDoリスト機能(CRUD) × ③ カレンダー機能 FullCalendar ④ いいね機能(Ajax) × ⑤ コメント機能(Ajax) × ⑥ フォロー機能 × ⑦ 宣言機能 × ⑧ わたしも機能(勝手に命名) × ⑨ つぶやき機能(CRUD) × ⑫ グラフ機能(ドーナツチャート) Chartkick ⑬ レベル表示機能 × ⑭ ランキング機能 × ⑮ 付箋機能(勝手に命名) × これらの機能の概要と2つの仕組み実現のために工夫した点・思いについて、ここから1機能ずつ解説したいと思います!
4. 機能の解説
ToDoリスト機能
概要
ToDoリスト機能です。使い方は、とてもシンプルです。①課題を登録
②課題がリスト化される
③完了ボタンを押すと完了済みに入る(完了済みから戻すのもできます!)
工夫した点①シンプル
まずはシンプルを心がけました。アプリ名にもなっているメイン部分ではありますが、色々機能があっても使いにくいと思ったのでここはシンプルに課題名と〆切日だけを表示させました。②リマインド
「〆切をうっかり忘れていた」というようなことを防ぐために〆切1日前、〆切当日、〆切が過ぎている課題のリマインド機能を付けました。
また、〆切が過ぎている課題にはリストに赤い砂時計が表示されるようにしました。③実施日の登録
課題登録時に、〆切の何日前にするかという課題実施日も登録してもらうようにしました。これは、課題を「いつやるか」を考える習慣を付けることは、スケジュール管理が得意になる上で重要だと考えているためです。この仕組みを利用してその習慣を身に付けてもらえたらいいなという思いを込めて付けました。カレンダー機能
概要
〆切を可視化できるカレンダーです。課題を登録すると、自動で〆切日のみ表示されるようになります。終わった課題は表示されません。それぞれの課題をクリックすると詳細画面に飛びます。
工夫した点
①シンプル
リスト機能と同じくこちらもシンプルを心がけました。
〆切日のみに絞ってカレンダーに表示させることで、〆切日がひと目で分かるようにしました。②〆切のカラー
通常は緑色のラベルで課題が表示されますが、〆切が過ぎている課題は赤でラベルが表示されます。パッと見て、「いますぐやるべき課題」が分かります。いいね・コメント・フォロー
概要
SNSにはお馴染みの3機能です。
工夫した点これらの機能自体に特別な工夫があるわけではないですが、SNSやっている人なら誰もが一度は味わったことのある「いいねやコメントをもらう喜び」「誰かにフォローされる喜び」を〆KiListユーザーにも味わってもらい、課題に取り組む際のモチベーションにしてもらいたいなという思いを込めて実装しました。
宣言機能(オリジナル)
概要
課題を登録した際に、宣言ボタンが表示されます。
押すと、「いつ何の課題をするか」をみんなのつぶやき一覧に投稿できます。
工夫した点
①手間いらず
無駄な行程を踏まずに済むように、文章を自分で入れなくても、ボタン1つですぐに宣言できるようにしました。②やらざるを得ない環境の仕組み化
みんなの前で宣言して、やらざるを得ない状況を作る仕組みを仕掛けました。自分で管理するだけではついつい「明日でいっか」ってなってしまいますが、他の人に宣言しちゃうと何かやらなきゃいけない気がしてくると思います。その効果を利用しました。わたしも機能(オリジナル)
概要
挙手のマークを押すと、他の人が宣言している課題を、自分の〆KiListにも登録できます。挙手のマークは、自分以外の他のユーザーの課題宣言の投稿にのみ表示されています。主に同じ大学、学部の人とかが使いやすい機能かと思います。
工夫した点
①手間いらず
他の人の宣言を見て、「あ、この課題自分もやらなきゃいけなかった!」と思った時に、余計な行程を辿らず、すぐに課題が登録できるようにと思い、この機能を付けました。②仲間意識・ライバル意識を活用
「友達がやるなら、自分も一緒に頑張ろう」という仲間意識や「あいつに負けないように自分も頑張らないと」というライバル意識をモチベーションにする方は結構多いと思います。そういう人たちに、積極的に課題を登録してもらえるようにと思い、この仕組みを仕掛けました。つぶやき機能
工夫した点
・ToDoリスト×SNS
孤独な環境だと、どうしても課題が進められない人は多いと思います。そこで、つぶやき機能(SNS的な要素)を使って他の学生と積極的にコミュニケーションを取りながら、みんなで課題に取り組める仕組みを作りたいと思い、実装しました。グラフ機能(ドーナツチャート)
概要
課題達成率(今まで登録した課題のうち、達成済みの課題数の割合)、〆切遵守率(達成した課題数のうち、〆切を守った課題数の割合)がドーナツチャートでグラフ化されます。課題を完了すると、〆切達成率・〆切順守率が変わっていることが分かります。
工夫した点
①課題に取り組む姿勢を数値化・可視化
努力を数字やグラフで可視化させ、モチベーション維持に繋げてくれたらいいなと思い、実装しました。②人に見られる環境の仕組み化
グラフはマイページに表示されています。そのページに飛んでくれば、自分の課題に取り組む姿勢が他の人の目に触れることになります。人に自分の努力値が見られている環境に置かれていることもまた頑張るモチベーションになるかなと思い、この機能を付けました。レベル表示機能
概要
課題の完了数が増えていくにつれてレベルが上がっていきます。
「ビギナー」「中級者」などクラスも表示されます。
レベルが高ければ高いほど、課題をしっかりと完了させているという証明になります。
工夫した点
①次のクラスを目指すワクワク感
ユーザーが「次はどんなクラスかな?」「私も〇〇クラス目指して頑張ろ!」と楽しめるようにして、頑張れるモチベーションにしてもらえたらなと思い、実装しました。
この辺のバリエーションはまだまだ増やす余地ありなので、さらに色々なクラスを用意して、ユーザーにワクワクしてもらえるような仕様にしていきたいと考えています。②遊び心
真面目すぎるアプリは、少し使うとすぐに飽きてしまいます。なので、所々遊び心を加えて、ユーザーに楽しんでもらいながら長く使ってもらえるようにと思い、「何やコレ」と言うようなクラスを用意しました。例えば、Lv.1のクラスは「赤ちゃん」です。かわいいですね。育てたくなりますね。
ランキング機能
概要
レベルが上位3名になると、ランキングにユーザー名とレベルが載ります。
工夫した点
・ランキングに載ることへのモチベーション
ランキングに載ることもまた、一種のモチベーションになると思います。
「ランキングに名前を載せるために課題を頑張ろう!」と思ってもらえるようにこの機能を付けました。
ただし、今のところ見ての通りあまりにもデザインがシンプル過ぎて、名前が載っても「何だかな〜」と言う感じなので、もう少しモチベーション上がるような見栄えを目指したところです。付箋機能
概要
登録した課題と〆切日が、付箋のような感じで表示されます。本日〆切、本日実施の課題もすぐに分かります。
ここから課題の詳細ページに飛ぶこともできます。
工夫した点
・アプリ使用中は〆切を意識
このアプリは、課題の〆切日を守るためのアプリなので、常に〆切を意識してもらう必要があります。通常であれば、〆KiListのページに行かないと〆切を見ることができないことになってしまいますが、この付箋機能をマイページとつぶやき一覧ページに載せることで、アプリを使っている最中は常に〆切を意識してもらえることになります。〆切のうっかり忘れの防止をさらに強化するために、この機能を実装しました。番外編:〆KiListの色について
今回〆KiListを作成するにあたって、カラーを下記の通り選択しました。
- メインカラー:ネイビー、オレンジ、ホワイト
- サブカラー:グレー、ブルー(ボタンにカーソル置いた時)
基本的には、メインカラーを使うように気をつけました。
自分はデザイン的な知識は全くないので、色で統一感を出すことでそれなりにまとまりのある感じを出そうという発想になり、その結果使う色を3色に絞りました。ただし、全部がこの色だと面白味がないので、ボタンにカーソルをのせた時やちょっとしたデザインの部分に関しては、グレーやブルーなど、メインカラーに比較的馴染みが良いであろうカラーを使うようにしました。
(カレンダーは土曜日のイメージが青や水色、日曜日のイメージが赤やピンクなので例外です)尚、一番のメインカラーはネイビーですが、これは青系の色の方が、「勉強」「課題」といった真面目な印象を与えやすいから選択しました。
そこにオレンジという暖色を加えたのは、〆KiListがSNS的な要素を持ち、「人との繋がり」「励まし合い」といった要素も含むからです。
ネイビー×オレンジという組み合わせが結構しっくりきたのでこれらの色をメインに使いました。
さいごに
長くなりましたが、以上です。
大学生の「課題が多すぎる」という悩みを解決するためには、
①課題に取り組むモチベーションが上がる仕組み
②課題のスケジュール管理をしやすくする仕組みこの2つの仕組みが必要で、この仕組みを実現するために、今回解説した12機能を付けたというお話でした。
ここまで読んでいただいてありがとうございます。予定
①この記事は、今のところ「思い」の部分が前面に出た記事になっておりますので、今後はそれぞれの機能についてどのように実装したかという技術的な部分も付け加えていけたらと思っています。
②今回は、機能という部分に着目しましたが、ポートフォリオ(このアプリ)の作成の全体的な解説記事は別で投稿します。それまでにAWSでのデプロイを頑張ります。
- 投稿日:2020-12-06T20:24:37+09:00
ローカル変数とインスタント変数の違い
現在、「Ruby on Rails 5 速習実践ガイド」を読みながら勉強をしているのですがローカル変数とインスタント変数についてあまり理解せずに進んでしまいました。
なので、きちんと理解するため記事にしてみました。
プログラミング初心者のため認識違いがあった場合などは是非ご指摘下さい。
ローカル変数とは
その場限りの一時的な変数です。メソッド内で定義したローカル変数はそのメソッドの中でしか使うことができず、他のメソッドからは使うことができません。
インスタント変数とは
オブジェクトの保持する変数です。オブジェクトのどのメソッドな内からも利用できます。
試したこと
今回、自分でMyClassを作ってみました。
class MyClass def method_1 number = 100 end def method_2 number end endそしてこのクラス (MyClass) のオブジェクトを作って、method_1を呼び出してみます。
> object = MyClass.new > object.method_1 => 100このメソッドにはnumberというローカル変数に100という数値のオブジェクトをいれています。
そのためメソッドを呼び出すと100という値が返ってきています。それに続けて、method_2を呼び出してみます。
> object.method_2 Traceback (most recent call last): ... NameError (undefined local variable or method `number' for #<MyClass:0x00007ffe439012580>)「numberという名前のローカル変数やメソッドは知りません」というエラーが表示されてしまいました。
ここではmethod_1で定義したnumberというローカル変数がmethod_2でも生き残っていれば表示されるはずです。
エラーが返ってきてしまったということは、method_1で使ったnumberは使えないという状況になりました。次にローカル変数ではなくインスタント変数を使ってみます。
class MyClass def method_1 @number = 100 end def method_2 @number end end> object = MyClass.new > object.method_1 => 100 > object.method_2 => 100今度は、method_2でエラーが出ず、無事に100という値が返ってきました。
ここで同じインスタント変数を利用できていることがわかります。まとめ
ローカル変数は1つのメソッドの中で一時的に使うデータを参照するために使います。
一方、インスタント変数は、特定のオブジェクトの内部で使いまわしたりできます。参考本
・ 現場で使える Ruby on rails 5 速習実践ガイド
- 投稿日:2020-12-06T20:24:37+09:00
ローカル変数とインスタンス変数の違い
現在、「Ruby on Rails 5 速習実践ガイド」を読みながら勉強をしているのですがローカル変数とインスタンス変数についてあまり理解せずに進んでしまいました。
なので、きちんと理解するため記事にしてみました。
プログラミング初心者のため認識違いがあった場合などは是非ご指摘下さい。
ローカル変数とは
その場限りの一時的な変数です。メソッド内で定義したローカル変数はそのメソッドの中でしか使うことができず、他のメソッドからは使うことができません。
インスタンス変数とは
オブジェクトの保持する変数です。オブジェクトのどのメソッドな内からも利用できます。
試したこと
今回、自分でMyClassを作ってみました。
class MyClass def method_1 number = 100 end def method_2 number end endそしてこのクラス (MyClass) のオブジェクトを作って、method_1を呼び出してみます。
> object = MyClass.new > object.method_1 => 100このメソッドにはnumberというローカル変数に100という数値のオブジェクトをいれています。
そのためメソッドを呼び出すと100という値が返ってきています。それに続けて、method_2を呼び出してみます。
> object.method_2 Traceback (most recent call last): ... NameError (undefined local variable or method `number' for #<MyClass:0x00007ffe439012580>)「numberという名前のローカル変数やメソッドは知りません」というエラーが表示されてしまいました。
ここではmethod_1で定義したnumberというローカル変数がmethod_2でも生き残っていれば表示されるはずです。
エラーが返ってきてしまったということは、method_1で使ったnumberは使えないという状況になりました。次にローカル変数ではなくインスタンス変数を使ってみます。
class MyClass def method_1 @number = 100 end def method_2 @number end end> object = MyClass.new > object.method_1 => 100 > object.method_2 => 100今度は、method_2でエラーが出ず、無事に100という値が返ってきました。
ここで同じインスタンス変数を利用できていることがわかります。まとめ
ローカル変数は1つのメソッドの中で一時的に使うデータを参照するために使います。
一方、インスタンス数は、特定のオブジェクトの内部で使いまわしたりできます。参考本
・ 現場で使える Ruby on rails 5 速習実践ガイド
- 投稿日:2020-12-06T20:15:38+09:00
Railsのカスタムバリデーション(ActiveModel::Validator)
はじめに
独自のバリデーションを実装する
validates_withに関して簡単にまとめます。バリデーションの作り方
app/validatorsフォルダにカスタムバリデーションを書いていきます。例えば、退社済みのスタッフの場合エラーが出る様なバリデーションを作る場合、下記の様になります。
class ActiveStaffValidator < ActiveModel::Validator def validate(record) if record.end_date < Date.today record.errors[:base] << "退社済みのスタッフです。" end end end使い方
使い方としては、対象のモデルのファイルに
validates_with ActiveStaffValidatorと記載するだけです。
- 投稿日:2020-12-06T19:59:36+09:00
Railsのカスタムバリデーション(validate_each)
はじめに
ActiveModel::EachValidatorを使うことで、独自のバリデーションを追加することができます。フォルダ作成
まず、
app/validatorsフォルダを作成します。この
validatorsフォルダに独自のバリデーションを追加していきます。バリデーション作成
例えば、カラーコードかどうかを判定したい場合に、
app/validatorsフォルダにcolor_validator.rbのファイルを作成し、下記の内容を記載します。class ColorValidator < ActiveModel::EachValidator PATTERN = /カラーコードかどうか判定するための正規表現を記載/.freeze def validate_each(record, attribute, value) unless value =~ PATTERN record.errors.add(attribute, "はカラーコードでなければいけません。") end end endこの様にすることで、値がカラーコードで無い場合にエラーを出すカスタムバリデーションを作成できました。
使い方
使い方としては対象のモデルに対して
validates :color_code, color: trueの様に
color_codeカラムにカラーコード以外の値が保存されるときにエラーを出す様にすることができます。
- 投稿日:2020-12-06T19:59:36+09:00
Railsのカスタムバリデーション(ActiveModel::EachValidator)
はじめに
ActiveModel::EachValidatorを使うことで、独自のバリデーションを追加することができます。フォルダ作成
まず、
app/validatorsフォルダを作成します。この
validatorsフォルダに独自のバリデーションを追加していきます。バリデーション作成
例えば、カラーコードかどうかを判定したい場合に、
app/validatorsフォルダにcolor_validator.rbのファイルを作成し、下記の内容を記載します。class ColorValidator < ActiveModel::EachValidator PATTERN = /カラーコードかどうか判定するための正規表現を記載/.freeze def validate_each(record, attribute, value) unless value =~ PATTERN record.errors.add(attribute, "はカラーコードでなければいけません。") end end endこの様にすることで、値がカラーコードで無い場合にエラーを出すカスタムバリデーションを作成できました。
使い方
使い方としては対象のモデルに対して
validates :color_code, color: trueの様に
color_codeカラムにカラーコード以外の値が保存されるときにエラーを出す様にすることができます。
- 投稿日:2020-12-06T19:23:04+09:00
micro:bitをRubyでプログラミングする「rb:-:bit」(rbbit)ライブラリの紹介
この記事は「micro:bit Advent Calendar 2020 - Qiita」の9日目の記事です。
2020年クリスマスを前に、micro:bitをRubyでコーディングできるようにするライブラリrbbitが公開されました。(正式名は、Rubyとmicro:bitがつながっているイメージで rb:-:bit だそうです。)
(rb:-:bit公式ページ より)1. はじめに
micro:bitを使えるプログラミング言語としては、今までブロック(MakeCode)、JavaScript(MakeCode)、Python(MakeCode、MicroPython)、Scratch3、Smalruby3、C/ C++ などがありました。
そこに、今回 Rubyが加わることになりました。MakeCodeのブロックによるプログラミングからステップアップする選択肢が、また一つ広がったことになります。
また、Ruby on Railsなどで幅広く使われているRubyの初心者向けの学習ツールとして、micro:bitが使えるようになった意義は大きいと思います。2. rb:-:bit とは
Rubyでmicro:bitを使えるようにするライブラリです。
仕組みとしては、micro:bitとパソコン(PC)をUSBケーブルで接続し、お互いがシリアル通信することでPCからmicro:bitに制御命令を送ったり、micro:bitからセンサーの情報をPCに送ることで、お互いのやりとりを可能にします。
これは、MakeCodeのようにmicro:bitにプログラムを転送して実行させる方式ではなく、Scratchで実行時にコマンドをScratch Linkによって送受信するイメージに近いです。
3. できること
対応
- LEDの点灯、消灯、文字の表示
- 音の出力※
- センサーの値の取得(加速度、傾き、明るさ、温度)
- ボタン押下状態の取得
※ micro:bit(v1.5)では、スピーカーの接続が必要
未対応
- 磁気センサー
- P0など入出力端子
- 無線通信
- タッチセンサー(v2.0)
- マイク(v2.0)
現状でも、micro:bitのほとんどの機能が使えるようになっています。
4. 使い方
micro:bitには、rb:-:bit用のシリアル通信を解釈する専用プログラムをあらかじめ書き込んでおきます。
PCには、Rubyとrbbitライブラリをインストールしておきます。そして、micro:bitを動かすプログラムをRubyで作ります。
micro:bitとPCをUSBケーブルで接続し、Rubyのプログラムを実行します。
5. 参考サイト
rb:-:bit公式ページ
https://spoolkitamura.github.io/rbbit/index.htmlrbbit GitHubページ
https://github.com/spoolkitamura/rbbitrbbit RubyGemsページ
https://rubygems.org/gems/rbbit6. 動作環境
A. 対応PC OS
- Windows
- macOS
- Linux
(PCには、Ruby、rbbitライブラリをインストールしておく)
B. 対応micro:bit
- micro:bit v1.5(従来のバージョン)
- micro:bit v2.0(2020.11.25 日本発売)
(micro:bitには、専用プログラムを書き込んでおく)
C. 接続
- USBケーブルによる有線接続
(Bluetoothによる無線接続は今後対応予定)
D. rb:-:bitバージョン
rb:-:bit(0.4.6) 2020.11.28
7. 準備(インストール)
ここでは概要だけ述べていきます。
詳しいインストール手順は、rb:-:bit公式ページ を見てください。1) Rubyのインストール
PCにRubyがインストールされている必要があります。
2) rbbitのインストール
PCにRubyのライブラリrbbitをインストールします。
3) micro:bitへ専用プログラムの書き込み
micro:bit用の専用プログラムをPCにダウンロードします。(v1.5用とv2.0用があります。)
ダウンロードしたプログラムをmicro:bitに書き込みます。
micro:bitのLEDが以下のように点灯すると、正しく書き込めています。
4) シリアルポート名の確認
micro:bitとPCをUSBケーブルをつないで、シリアル通信をするためのmicro:bitのポート(デバイス)名を確認します。
(USBケーブルを抜き差しすると、毎回シリアルポート名の確認が必要です。)5) 環境変数の設定
確認したシリアルポート名を環境変数に設定しておきます。
(コンソールを終了するとこの設定は消えます。)あるいは、プログラム実行時に指定することも可能です。
8. rb:-:bitを使ってみる
rb:-:bitには3つの使い方があります。
A. 簡易対話モード
1行ずつコマンドを実行するモードです。
起動するには、コンソール(ターミナル)で
rbbitと入力します。micro:bit>と表示されたら、うまく起動しています。
onやoffあるいは、on 2 2などとコンソールに打って、micro:bitがその通り動くか確認してみてください。micro:bit> onmicro:bit> offmicro:bit> on 2 2(※ 終了するには、
exitと打ちます。)コマンドの一覧はこちらのページ に載っています。
B. ブラウザ対話モード(WebSocketサーバ機能)
ブラウザを使って、GUIでセンサーの値を表示したり、制御したりします。
このモードを起動させる方法も簡易対話モードと同じで、コンソール(ターミナル)で
rbbitと入力します。micro:bit>簡易対話モードと同じに見えますが、これでブラウザ対話モードも起動しています。(簡易対話モードとブラウザ対話モードは常に同時に起動します。)
サンプルプログラムのページ のリンクを直接クリックすると、ブラウザで新しいページが開いてサンプルの実行結果が表示されます。
(※ Safariなどではセキュリティの関係で、うまく表示されないことがあります。その場合は、Chromeを使うか、サンプルプログラムを一旦PCにダウンロードしてからダブルクリックしてブラウザを開いてください。)
ブラウザ対話モードは、より正確にいうとWebSocketサーバが起動してmicro:bitからの情報をクライアントに配信するWebSocket通信モードです。そのため、プログラミング言語を問わずWebSocket通信のクライアントプログラムさえ書けばmicro:bitを操作することができるという、汎用的な用途を狙っているそうです。(よくわかってない…)
C. プログラミングモード(Rubyクラスライブラリ)
実際に自分でmicro:bitを動かすプログラムを作るには、Rubyでプログラムを書くことになります。
やり方は通常のRubyのプログラムの作り方/実行の仕方と同じです。エディタでRubyのプログラムを書いて、保存したプログラムをコンソール(ターミナル)で実行することで、micro:bitが操作できます。
1) rbbitライブラリを使えるようにする
Rubyのプログラム冒頭に、
require 'rbbit.rb'と1行書くことで、rb:-:bitの機能が使えるようになります。
2) rb:-:bitの文法
- Rubyクラスライブラリ リファレンス https://spoolkitamura.github.io/rbbit/man_console.html
を見てください。
3) 実行方法
プログラムを実行するには、
7-4) シリアルポート名の確認で行ったシリアルポートの指定が必要です。
7-5) 環境変数の設定で、あらかじめ行っておくか;> set MB_PORT=COM5 > ruby s1_heart.rb実行時にプログラム名と共に指定します;
> ruby s1_heart.rb COM59. rb:-:bitによるプログラミング例
最初は、こちらのページ のサンプルプログラムをダウンロードして実行してみるのが良いでしょう。
(※ このページ のサンプルプログラムのリンクをクリックしても、中身が見れるだけで実行はされません。)
サンプルプログラムの実行方法も同じページ で説明されています。
ただし、実行するにはサンプルプログラムを解凍して、コンソール(ターミナル)のカレントディレクトリをサンプルプログラムのあるディレクトリの場所にcdで移動しておかないといけません。1) サンプルプログラム(s1_heart.rb)
require 'rbbit.rb' # 点滅するハート =begin ・ハートマークが 5回点滅(操作不要) =end mb = Rbbit::Microbit.new(ARGV[0]) pattern = [ [0, 1, 0, 1, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0] ] 5.times do mb.led_show(pattern) sleep 0.5 mb.led_off sleep 0.5 end mb.led_puts("OK!") mb.close(5000)
Rbbit:Microbit.newでインスタンスを生成し、インスタンスメソッドを使ってmicro:bitを操作します。メソッドは
led_show、led_offやsound_play、button_down?など、分かりやすい名前になっています。(※ 最後に
mb.close(5000)(5秒後に通信切断)としているのは、macOSだとプログラムが終了すると、その時点でmicro:bitがリセットされてしまうのを防ぐためです。)2) 実行結果
10. 困ったときは
公式ページ>マニュアル>よくある質問
が用意されています。11. さいごに
micro:bitをRubyからも扱えるようになり、micro:bitの魅力が一段と増しました。Rubyによるmicro:bitプログラミングは、小学校以降の中学、高校、大学などでも、プログラミング教育に十分活用できる可能性があると思います。
rb:-:bitによって、かなり手軽にRubyのプログラミングが始められるようになりました。ぜひ試してみてみてください。
- 投稿日:2020-12-06T18:58:55+09:00
【Rails6】Action mailerでメール送信までを解説してみる。(MailHogも使うよ)
はじめに
今回は、
Action mailerによってアプリケーションからメールを送信する流れまでを解説していきます。また
Action mailerを最低限に絞って解説していくので、Railsの他の機能は解説しません?♂️Action mailerでメール送信する
【1】MailHogの導入
MailHogを使うことで開発環境におけるメール送受信の確認をすることができます。
Railsではletter_openerというgemが有名ですがsprockets環境でないと導入できないのです。
つまり、sprockets環境出なかったり、RailsAPIモードの場合は使うことができません。(間違っている場合は、コメントしてください?♂️)そこで、
MailHogを採用します。MailHogは開発環境のDocker-composeに下記のように書くことで手軽に導入することができます!!docker-compose.ymlmailhog: image: mailhog/mailhog:v1.0.0 ports: - "8025:8025"あとは、
http://localhost:8025/でUI上でメールが正しく送られているか確認することができます。便利ですね!【2】設定ファイルを編集
config/environments/development.rbで下記のコードを記述してください。action_mailerに必要な設定です。とりあえず、開発環境だけしておきます。
config/environments/development.rbconfig.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'mailhog', port: 1025 }【3】メーラーを生成
下記のコマンドで
mailerを作成することができます。rails g mailer UserMailer
mailerとはRailsのコントローラーとほぼ一緒だと考えてもいいかもしれません。【4】メール送信処理を記述
app/mailers/user_mailer.rbにメールを送信する処理を書いていきます。app/mailers/user_mailer.rbclass UserMailer < ApplicationMailer def new_registration_email(user) @user = user mail subject: '新規アカウント登録されました', to: @user.email end end今回は、仮に新規会員登録のタイミングでメールを送信することを想定しています。
【5】view以下にメール本文を書いていく。
app/views/user_mailer/new_registration_email.erbに実際に送られるメールの本文を記述していきます。app/views/user_mailer/new_registration_email.erb<%= @user.name %> 様 会員登録が完了しました。 URLはこちらです。 <%= user_url(@user) %>【6】任意の箇所でメソッドを走らせる。
UserMailer.new_registration_email(@user).deliver上記のように記述することで、メールを送信できるようになります。下記はUserがCreateされるタイミングでメールを送信しています。
app/models/user.rbclass User < ApplicationRecord # 略 after_create :send_email_for_new_registration private def send_email_for_new_registration UserMailer.new_registration_email(self).deliver end end最後に
駆け足でしたが、以上です!
簡単に実装できてしまいましたね。すごい。。。
ではでは?
- 投稿日:2020-12-06T18:55:33+09:00
第6回
variable
お題
受け取った引数ARGVをnameという変数(variable)に代入してそれを打ち出すcodeを書け.
> ruby name_variable.rb Rudy Rudy簡単な解説
rubyの変数は型宣言の必要性がありません.文脈に合わせて適当に型が定められます.イコールで代入されます.
name = 'Rudy'なんかです.
詳しい解法
> ruby name_variable.rb Rudyとしましょう.
ruby: No such file or directory -- name_variable.rb (LoadError)というエラーが返ってきますよね.そんなファイルないよって.なら作ります.
> emacs name_variable.rbとしてemacsを起動して
p "Rudy"と打ち込んでsaveしましょう.
> ruby name_variable.rb Rudy "Rudy"
類題
さてこの後,
- nameに代入してRudyと打ち出すようにrefactoringしてください.
- ARGVを受け取って,自分の名前を返すようにrefactoringしてくださいhello(name) name = ARGV[0] puts "Hello #{name}"method
お題
> ruby hello_method.rb Rudy Hell Rudy.と返すhello methodを作りなさい.
解説
Rubyではfunctionやprocedureなどのまとまりはmethodを定義(definition)することになります.methodは0個以上の引数(argument)を取ることができます.例えば次の通りです.
def hello(name) p name end解法
> ruby hello_method.rb Rudyとして見ましょう.もちろん動きませんよね.emacsでhello_method.rbを編集します.
> emacs hello_method.rb何ですが,methodの中身ではなく呼び出す方から考えます.普通に,
hello(name)と打ち込んで動かして見てください.
> ruby hello_method.rb Rudy hello_method.rb:1:in `<main>': undefined local variable or method `name' for main:Object (NameError)というエラーが返ってきたはずです.nameという変数やmethodがundefineやと怒られています.そこで今まで学んできたのを思い出して,nameにARGVを代入します.
name = ARGV[0] hello(name)次のerrorは
> ruby hello_method.rb Rudy hello_method.rb:2:in `<main>': undefined method `hello' for main:Object (NoMethodError)でhelloっていうmethodがないよですね.
類題
先の解法を参照してhello メソッドを完成させてください.
def hello(name) puts "Hello #{name}." end name = ARGV[0] hello(name)ここで学んだこと
- ruby
- variable
- method
- argument
TDD
codingの最終目標
こういうcodingの仕方はTDD(Test Driven Development:テスト駆動開発)と呼ばれています.
- テストを作る
- エラーを出す(red)
- エラーをなくす(green)
- codeを綺麗にする(refactoring)
です.codingの最終目標は
clean code that works動く綺麗なコードを作ることです.順番は,まず動かして,それからこそこそと綺麗にするです.えっと,もし,あなたが,
- codeを書くまえに設計すべき
- コピペは悪なんていう,マントラを信じているならこのprogramming styleを提唱し始めたKent Beckの文章を載せておきます.よーーく心に刻んでください.
もしあなたがプログラミング嫌いならば,少し心が晴れると思いますよ.俺のせいじゃないって.
clean code that works
TDD by Example (Kent Beck) p.13
目指すのは,動作するきれいなコードだ(このRon Jeffriesの簡潔な表現は素晴らしい).動作するきれいなコードは,偉大なプログラマでもすぐには書けないことがあるし,普通のプログラマならなおさらだ(私もそうだ).
=ここは分割統治しよう.=各個撃破だぜ,ベイビー.最初に「動作する」に取り組み,その後で「きれいな」に取り組む.この方法はアーキテクチャ駆動とは正反対だ.アーキテクチャ駆動は「きれいなコード」に最初に取り組み,そのうえで苦心してあちこち設計の辻褄を合わせながらどうにか「動作する」を実現させる.TDD by Example (Kent Beck) p.11
The goal is clean code that works(thenks to Ron Jeffries for this pithy summary).Clean code that works is out of the reach of even the best programmerssome of the time,and out of the reach of most programmers(like me)most of the time.Divide and conquer, baby.First we'll solve the "that works" part of the problem.Then we'll solve the "clean code" part.This is the opposite of architecture-driven development,where you solve "clean code" first,then scramble around trying to integrate into the design the things you learn as you solve the "that works" problem.
phases and speed
TDD by Example (Kent Beck) p.30
グリーンバーを出す小さなステップはどんなものだろうか.Dollarクラスを丸ごとコピーして,DollarをFrancに書き換えるのはどうだろう.
ちょっと待った.これで唾棄すべき糞コードの出来上がりだとあざ笑う声が聞こえる.その声は続けて言う.コピー&ペーストによる再利用は抽象化の敗北であり,きれいな設計を殺すと.
イラっとしただろうか.なら深呼吸だ.鼻から息を吸い込んで,3秒止めて口から吐き出す.オーケー?さて,サイクルにはフェーズがあることを思い出してほしい(中には数秒で通り過ぎるものもあるが,フェーズはフェーズだ).
1. テストを書く.
2. コンパイラを通す.
3. テストを走らせ,失敗を確認する.
4. テストを通す.
5. 重複を排除する.各フェーズにはフェーズなりの目的と解決法があり,価値観も異なっている.最初の3つのフェーズはなるべく速く通過して,新しい機能がどの状態にあるのかわかるところまで行きたい.そこにたどり着くためには,どのような罪をおかしてもよい.その短い時間だけは,速度が設計よりも重要だからだ.
1つ心配なのは,私がここに書いていることが,良い設計の原則を無視してよいという免罪符になってしまうことだ.チームに対して「Kent Beckが設計なんてどうでもいいって書いてたよ」などと言い始めるのは,ちょっと待ってほしい.サイクルはまだ終わっていない.4つ足のアーロンチェアは倒れる.最初の4つのステップは,5つ目がなければ無意味だ.正しい設計を,正しいタイミングで行う.動かしてから,正しくする.
ここまで言っておけば安心だろう.これで読者の皆さんは重複を排除するまで誰にもコードを見せないはずだ(ただし,ペアプロ相手は除く)
TDD by Example (Kent Beck) p.23
What short step will get us to a green bar?Copying the Dollar code and replacing Dollar with Franc.
Stop. Hold on.I can hear the aesthetically inclined among you sneering and spitting.Copy-and-paste reuse?The death of abstraction?The killer of clean design?
If you're upset, take a cleanthing breath.In through the nose … hold it 1, 2, 3… out through the mouth.There. Remember, our cycle has different phases(they go by quickly, often in seconds, but they are phases.):
1. Write a test.
1. Make it compile.
2. Run it to see that it fails.
2. Make it run.
3. Remove duplication.(Make it right.)The different phases have different purposes.They call for different styles of solution, different aesthetic viewpoints.The first three phases need to go by quickly,so we get to a known state with the new functionality.We can commit any number of sins to get there,because speed trumps design,just for that brief moment.
Now I'm worried.I've given you a license to abandon all the principles of good design.Off you go to your teams –"Kent says all that design stuff doesn't matter."Halt. The cycle is not complete.A four-legged Aeron chair falls over.The first four steps of the cycle won't work without the fifth.Good design at good times.Make it run, make it right.
There, I feel better.Now I'm sure you won't show anyone except your partner your codeuntil you've removed the duplication.Where were we?Ah, yes.Violating all the tenets of good design in the interest of speed(penance for our sin will occupy the next several chapters).
おまけ
言語は英語から
これをmethodにしたら,
def func(hoge) puts "Hello #{hoge}." end hoho = ARGV[0] func(hoho)これを動かしてみましょう.
> ruby hello.rb bobとちゃんと動きます.これでは何をしているのかわからないので,コメントをつけましょう.
# method: func # input: hoge is a name # output: puts greetings # return: nil def func(hoge) puts "Hello #{hoge}." end honya = ARGV[0] # get hoho from argv func(honya) # call hello with a name honya英語でしっかりとコメントが書ければ世界中に通用するcodeが書ける…んでしょうかね?コメントをぐちゃぐちゃ書くんじゃなくて,もっとわかりやすい名前(method名,変数名)にしたくなるでしょう?
def puts_hello name puts "Hello #{name}." end name = ARGV[0] puts_hello nameこっちの方が短くてスッキリしていて圧倒的にいいでしょ? 適切な英単語を使えば,要らん説明が省けます.これが言語は英語からという意味です.
長くなったら,隠せ
もしoptionのnameを打つのを忘れたら,問い合わせてくれると,user interfaceという感じがもっとするでしょう?
name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp endというのをname=の下につけましょう.ちょっと動かして見ましょう.
> ruby hello.rb意図通りに動いていますか? でもmain loopが長くなってきちゃいました.そこで,これもmethodに切り出します.領域を指定して(C-spaceで先頭を指定して移動),C-wでcut, 移動してC-yでyankです.
def gets_name name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp end return name end name = gets_nameこの時,領域を指定してM-x indent-regionとしてください.あるいはC-x TAB.これだけでもだいぶ読みやすくなったでしょ?
もっとできます.main loopにcursorを持って行って,'C-c @ C-l'と打ってみてください.
def puts_hello name...end def gets_name...end name = gets_name puts_hello nameこれがoutlineによるtoggle表示からきたすごいメタファなんですよ.何をしているのか知らなくていい部分は隠してしまおうというのが,methodに切り分ける理由なんです.
今日の教え- editor -
ここで示した優秀なeditorのmeritは納得いただけましたでしょうか?必須操作を少しだけリストアップしておくと,
1. editのkey-bind
2. syntax high_lighting
3. code hiding, show
4. block copy, 移動
5. query-replace
6. shellとの連携
- source ~/grad_members_20f/members/yoshida/c2_name_method_hello.org
- 投稿日:2020-12-06T18:53:11+09:00
Neo4jをActiveRecord感覚で扱えるActiveGraphを触ってみた
こんにちは。@mshibuyaです。
グラフデータベースNeo4j向けのActiveModel準拠のOGM(Object Graph Mapping, ORMのグラフ版ですね)であるActiveGraphを触ってみる機会があったのでご紹介します。なおこの記事はRails Advent Calendar 2020の6日目のエントリーです。
グラフデータベースとは
データ構造としてのグラフを扱うことに最適化されたデータベースシステムです。ノードとエッジから表現され、様々な物事同士の関連関係を効果的に扱うことができます。Amazon Neptuneとしてフルマネージドのグラフデータベースサービスも登場したりしていて、徐々に利用範囲を広げつつあるのではないでしょうか。
とはいえ、このへんの話はあんまり詳しくないので深くは語れないです。なんかグラフ理論ってかっこよさげだしよくない?程度のノリです…
ActiveGraphはグラフデータベースNeo4jをバックエンドとして利用します。もともとNeo4j.rbと呼ばれていたものが最近名前が変わったようですね。
触ってみる
Docker ComposeでNeo4jを立ち上げます。ActiveGraphが対応済みであるバージョン4.0を選択
version: '3' services: neo4j: image: neo4j:4.0 ports: - "7474:7474" - "7687:7687" volumes: - ./neo4j:/dataneo4j-ruby-driverに必要なseaboltをinstall
$ brew install michael-simons/homebrew-seabolt/seaboltrails newする
$ rails new graph_app -T -O -m https://raw.githubusercontent.com/neo4jrb/activegraph/master/docs/activegraph.rbconfig/neo4j.ymlを作成
development: url: bolt://localhost:7687 test: url: neo4j://localhost:7688モデルを作成
app/model/person.rb
class Person include ActiveGraph::Node property :name endapp/model/friendship.rb
class Friendship include ActiveGraph::Relationship from_class :Person to_class :Person property :since, type: DateTime endこのへんで
Neo4j::Driver::Exceptions::AuthenticationException (Permission denied)が出て困ったんですが、Neo4j側でパスワードを変更したら出なくなりました。とりあえず深追いはしません。。rails consoleから遊んでみます
irb(main):001:0> john = Person.create name: 'john' CYPHER CREATE (n:`Person`) SET n = $props RETURN n | {:props=>{:uuid=>"ae128a36-4e0b-4879-9213-9d5ec0b0b726", :name=>"john"}} BOLT: 0ms irb(main):002:0> paul = Person.create name: 'paul' CYPHER CREATE (n:`Person`) SET n = $props RETURN n | {:props=>{:uuid=>"5c8987da-de09-4673-b366-a002b491be65", :name=>"paul"}} BOLT: 0ms irb(main):003:0> Friendship.create(from_node: john, to_node: paul, since: Time.now) BOLT: 0ms BOLT: 0ms CYPHER MATCH (from_node), (to_node) WHERE (ID(from_node) = $from_node_id) AND (ID(to_node) = $to_node_id) CREATE (from_node)-[rel:`FRIENDSHIP` $rel_create_props]->(to_node) SET rel.`since` = $setter_rel_since RETURN rel | {:from_node_id=>0, :to_node_id=>2, :setter_rel_since=>1607243457, :rel_create_props=>{}} BOLT: 0ms => #<Friendship since: Sun, 06 Dec 2020 08:30:57 +0000> irb(main):004:0> people = 1.upto(100).map {|i| Person.create name: "person#{i}" } ... irb(main):005:0> 300.times.each { Friendship.create from_node: people.sample, to_node: people.sample } ... irb(main):006:0> Person.query_as(:p).where('size((p)-->()) > 5').count # 5人以上friendのいるPersonの数を取得 CYPHER MATCH (p:`Person`) WHERE (size((p)-->()) > 5) RETURN count(*) BOLT: 0ms => 6ちょっと凝ったクエリをしようとするとNeo4jのクエリ言語であるCypherの知識が求められはするんですが、なかなか面白いです。最短距離を求めるだとか、リコメンデーションに利用したりとか想像は膨らみます…
本当は最近RailsAdminに寄せられたNeo4j対応を試してみるところまで行きたかったのですが、時間がないので今日はここまでで。
よいRailsライフをお過ごしくださいー
- 投稿日:2020-12-06T18:45:46+09:00
Rspec 結合テストコードでのSelect要素の取得方法
はじめに
現在、転職活動のポートフォリオとして車のレビューサイトを作成しており、
そこで私自身が詰まった箇所の解決方法をアウトプットしていきたいと思います!Rspecをつかった結合テストコード
今作成中の車のレビューサイト「Car-Review」にてユーザー登録機能やレビュー投稿機能、いいね機能など実装ができたので下記のように結合テストコードを書いていました。
一部抜粋spec/system/reviews_spec.rbrequire 'rails_helper' RSpec.describe "レビュー投稿", type: :system do before do @user = FactoryBot.create(:user) @review = FactoryBot.build(:review) end context 'レビュー投稿できるとき' do it 'ログインしたユーザーは新規投稿できる' do # ログインする visit new_user_session_path fill_in 'user[email]', with: @user.email fill_in 'user[password]', with: @user.password find('input[name="commit"]').click expect(current_path).to eq root_path # 新規投稿ページへのリンクがあることを確認する expect(page).to have_content('新規投稿') # 投稿ページに移動する visit new_review_path # フォームに情報を入力する select @review.automaker.name, from: 'review[automaker_id]' fill_in 'review[model_of_car]', with: @review.model_of_car fill_in 'review[grade]', with: @review.grade select @review.era_name.name, from: 'review[era_name_id]' fill_in 'review[model_year]', with: @review.model_year select '3点', from: 'review[design_id]' select '3点', from: 'review[driving_performance_id]' select '3点', from: 'review[ride_comfort_id]' select '3点', from: 'review[lording_id]' select '3点', from: 'review[fuel_economy_id]' select '3点', from: 'review[price_id]' fill_in 'review[good_point]', with: @review.good_point fill_in 'review[bad_point]', with: @review.bad_point # 送信するとReviewモデルのカウントが1上がることを確認する expect{ find('input[name="commit"]').click }.to change { Review.count }.by(1) # トップページに遷移していることを確認する expect(current_path).to eq root_path # トップページには先ほど投稿した内容のレビューが存在することを確認する(メーカー、車種、投稿者) expect(page).to have_content(@review.automaker.name) expect(page).to have_content(@review.model_of_car) expect(page).to have_content(@user.nickname) endこんな感じで次にReviewモデルの結合テストコードを書いていたら…
選択済みSelect要素の取得
今回の本題で、レビュー編集の結合テストコードを書こうとしたのですが、編集の画面に遷移してそこではすでに投稿済みの内容がフォームに入っていることを確認しなければなりませんでした。
views/reveiws/edit.html.erb<div class="form-group"> <label class="control-label">メーカー</label> <%= f.collection_select(:automaker_id, Automaker.all, :id, :name, {selected: [@review.automaker_id]}, class:"form-control") %> <div>spec/system/reviews_spec.rbexpect( find('要素').value ).to eq "#{@review1.automaker_id}"*viewファイルはActive HashとSelectタグを使いドロップダウンボックスを作ってます
上記のfindメソッドで要素を取得しそのvalue(=id)と、既に投稿してあるレビュー1のautomaker_idが一致すればそのページに投稿した内容があることが確認できます。
この'要素'の取得で躓いてしまいました。
解決方法
色々調べた結果下記の方法で解決することができました!
spec/system/reviews_spec.rbexpect( find('#review_automaker_id').value ).to eq "#{@review1.automaker_id}"スクショはデベロッパーツールにて該当箇所を切り取ったものです。
すごく簡単な事だったのですが、'#'をつければidで要素が取得できてしまうみたいです!!
恐らく基本的なやり方だとは思いますが、とても勉強になりました…!まだまだ勉強を初めて2,3ヶ月のため間違ったことを書いていましたら
コメントにて教えていただけるととても嬉しいです。次回はいいね機能の実装なんかの記事がかければと思っています!
参考文献
https://stackoverrun.com/ja/q/3065712
こちらの質問の回答を参考にさせていただきました。
ありがとうございました。
- 投稿日:2020-12-06T18:34:33+09:00
チャート式ruby-I(puts)
puts hello_world
お題
まずはhello_worldですね.
Hello world.と打ち出すプログラムを作ります.
解説
rubyでStringsを打ち出すのにはいくつかの方法があります.どれを使ってもいいですし,rubyistは状況に応じて全てを使います.そのほかにもいくつもありますが,まずはこれを覚えましょう.
Stringはシングルコーテーション'で囲うのと,ダブルで囲うのの二種類があります.シングルは中身をいじらないとき,ダブル"はちょこちょこいじるときです.これは後で見て行きます.
詳しい解法
まずはシングルで囲って,
puts 'hello world'を試しましょう.
> mkdir codes > cd codes > emacs puts_hello_world.rbとしてemacsを開いてcodeを打ち込んでください.c-x c-sでsaveしたらc-zで一時中断して,
> ruby puts_hello_world.rbとして走らせて見てください.動いた?
類題
pとかprintとかも試して見てください.違いを観察して,#でコメントをつけてp_print_hello_world.rbに書きなさい.
getsなんだけど,ARGVで行きます!
お題
> ruby hello_name.rb Rudyと打ち込んだ時に,
Hello Rudy.と返ってくるcodeを書け.
簡単な解説
putsしたら普通はgetsなんですが,目的の一つであるshell環境ではcommand line interfaceで作業をするためにARGVというのを使って行きます.
puts ARGV[0]とhello_name.rbに打ち込んで,
> ruby hello_name.rb Rudyとしてください.どうよ? うちの愛犬の名前は出たやろか?
ARGVというのは引数(argument)配列の0番目を意味しています.unix shell上ではcommandにoptionなんかの引数を直接渡すのが普通です.そのためにARGVというのは普通に用意されています.
次に"Hello Rudy."と打ち出させることをかんがえます.これをするにはいくつかの方法があります.これもいろいろ試して見てください.
Cからの人は,printfもありです.
printf("Hello %s.\n", ARGV[0])でも慣れてくると冗長なんで使わなくなります.多分使うのは,数値計算の出力formatを揃えたいときぐらいでしょうね.
詳しい解法
まずは動作させて見ます.
> ruby hello_name.rb Rudy Rudyって返ってます? これを変更します.
> psでemacsが今どういう状態かを確認して,fgあるいはemacs hell_name.rbで起動します.
puts "Hello #{ARGV[0]}"がこういう状況ではよく使われます.ちゃんとでています?
類題
次に"Hello Rudy."というのをどこかへ保存することを考えます.
ruby hello_name.rb bob > hello_name.txtとしてhello_name.txtに自分への挨拶を出力させて見てください.
Hello bob.とかね.'>'は,出力先を指定したtxtに変更(re-direct)するshellの機能です.
cat hello_name.txtで中身をcat(con-cat-inate)できます.
Footnotes:
1DEFINITION NOT FOUND.
- source ~/grad_members_20f/members/yoshida/c1_puts.org
- 投稿日:2020-12-06T18:29:28+09:00
チャート式ruby-I(puts)
puts hello_world
お題
まずはhello_worldですね.
Hello world.と打ち出すプログラムを作ります.
解説
rubyでStringsを打ち出すのにはいくつかの方法があります.どれを使ってもいいですし,rubyistは状況に応じて全てを使います.そのほかにもいくつもありますが,まずはこれを覚えましょう.
Stringはシングルコーテーション'で囲うのと,ダブルで囲うのの二種類があります.シングルは中身をいじらないとき,ダブル"はちょこちょこいじるときです.これは後で見て行きます.
詳しい解法
まずはシングルで囲って,
puts 'hello world'を試しましょう.
> mkdir codes > cd codes > emacs puts_hello_world.rbとしてemacsを開いてcodeを打ち込んでください.c-x c-sでsaveしたらc-zで一時中断して,
> ruby puts_hello_world.rbとして走らせて見てください.動いた?
類題
pとかprintとかも試して見てください.違いを観察して,#でコメントをつけてp_print_hello_world.rbに書きなさい.
getsなんだけど,ARGVで行きます!
お題
> ruby hello_name.rb Rudyと打ち込んだ時に,
Hello Rudy.と返ってくるcodeを書け.
簡単な解説
putsしたら普通はgetsなんですが,目的の一つであるshell環境ではcommand line interfaceで作業をするためにARGVというのを使って行きます.
puts ARGV[0]とhello_name.rbに打ち込んで,
> ruby hello_name.rb Rudyとしてください.どうよ? うちの愛犬の名前は出たやろか?
ARGVというのは引数(argument)配列の0番目を意味しています.unix shell上ではcommandにoptionなんかの引数を直接渡すのが普通です.そのためにARGVというのは普通に用意されています.
次に"Hello Rudy."と打ち出させることをかんがえます.これをするにはいくつかの方法があります.これもいろいろ試して見てください.
Cからの人は,printfもありです.
printf("Hello %s.\n", ARGV[0])でも慣れてくると冗長なんで使わなくなります.多分使うのは,数値計算の出力formatを揃えたいときぐらいでしょうね.
詳しい解法
まずは動作させて見ます.
> ruby hello_name.rb Rudy Rudyって返ってます? これを変更します.
> psでemacsが今どういう状態かを確認して,fgあるいはemacs hell_name.rbで起動します.
puts "Hello #{ARGV[0]}"がこういう状況ではよく使われます.ちゃんとでています?
類題
次に"Hello Rudy."というのをどこかへ保存することを考えます.
ruby hello_name.rb bob > hello_name.txtとしてhello_name.txtに自分への挨拶を出力させて見てください.
Hello bob.とかね.'>'は,出力先を指定したtxtに変更(re-direct)するshellの機能です.
cat hello_name.txtで中身をcat(con-cat-inate)できます.
Footnotes:
1DEFINITION NOT FOUND.
- source ~/grad_members_20f/members/yoshida/c1_puts.org
- 投稿日:2020-12-06T18:07:48+09:00
google-cloud-rubyがなぜかPythonを呼び出している件について
BigQueryの運用を行っていると定期的に無駄なテーブルを削除することは良くあると思います。
テーブル数が少ない場合はwebからぽちぽちと削除するので対応可能ですが、テーブル数が多い場合はスクリプトを作って削除したほうが楽です。最初は以下のようなスクリプトを書いていたのですが、削除対象のテーブル数が膨大なため、なかなか終わりませんでした。
※ロギング部分は省略require 'google/cloud/bigquery' table_names = [削除したいテーブル名の配列] project_name = プロジェクト名 dataset_name = データセット名 table_names.each do |table_name| bq_client = ::Google::Cloud::Bigquery.new(project: project_name) dataset = bq_client.dataset(dataset_name) table = dataset.table(table_name) table.delete endテーブルの削除処理はクライアントサイドのCPU・メモリーをほぼ使わず、ほとんどの待ち時間がBigQuery側での処理待をポーリングしているだけであるため、parallelというgemを使って並列化しました。
https://github.com/grosser/parallelRubyのマルチスレッド処理の実装はGVLによって同時に実行されるスレッドが1つだけになってしまっていますが、IO系のブロッキング処理に対してはGVLの解放をするので、今回のケースでは高速化が見込まれます。
require 'google/cloud/bigquery' require 'parallel' table_names = [削除したいテーブル名の配列] project_name = プロジェクト名 dataset_name = データセット名 ::Parallel.each(table_names, in_threads: 30).each do |table_name| bq_client = ::Google::Cloud::Bigquery.new(project: project_name) dataset = bq_client.dataset(dataset_name) table = dataset.table(table_name) table.delete endこれで、爆速になると思いプログラムを実行したところ、一瞬でCPU使用率が100%に張り付きました。
あまりにもこのプログラムがCPUを使うせいで、discordで通話中の相手から「やたらエコーかかっているんですが、風呂場で仕事してます?」と言われてしまいました。
discordはクライアントサイドで音声のノイズ除去などの信号処理をしているらしいというムダ知識が1つ増えました。さて、あまりにもCPUを使いすぎるので、ちょっと気になってdtraceでシステムコール呼び出しの様子を調べてみたら、大量のforkが呼ばれていました。
どんなサブプロセスを生成しているのかを確認するために、topコマンドを実行したところ、なぜかRubyが大量のPythonを呼び出していることが分かりました。
CPUが100%になる原因はこれです。では、google-cloud-rubyのどこコードがPythonを呼び出しているのでしょうか?
ソースコードを確認していたら見つかりました。gcloud_json = IO.popen("#{gcloud} #{GCLOUD_CONFIG_COMMAND}", &:read)このpopenメソッドの第一引数は部分は最終的に
gcloud config config-helper --format json --verbosity noneになります。
gcloudコマンドはPythonで実装されているため、このpopenによってPythonが呼び出されていました。この処理はGCPクライアントインスタンスの初期化をする際に呼ばれる処理で、システムデフォルトの認証情報を取得するものです。
::Google::Cloud::Bigquery.newをループの中で毎回呼び出す必要はなかったので、ループの外に出して1回だけ呼ばれるようにしました。require 'google/cloud/bigquery' require 'parallel' table_names = [削除したいテーブル名の配列] project_name = プロジェクト名 dataset_name = データセット名 bq_client = ::Google::Cloud::Bigquery.new(project: project_name) ::Parallel.each(table_names, in_threads: 30).each do |table_name| dataset = bq_client.dataset(dataset_name) table = dataset.table(table_name) table.delete endこれにより、CPUが100%に張り付くことはなくなり、またテーブルの削除速度も大幅に向上しました。
- 投稿日:2020-12-06T17:53:51+09:00
【Rails】PrimaryキーをUUIDにしてみる。~MySQL~
はじめに
今回は
gem(ライブラリ)等を使わずに、PrimaryキーをUUIDにする方法(MySQLの場合)を解説していこうと思います!また、この記事では
Userモデルを作成する流れで、PrimaryキーにUUIDを設定する流れを実践していきます。UserモデルのPrimaryキーをUUIDにする
【1】Userモデルを作成
ともかく、モデルを作成しましょう。今回は「試し」なので、カラムは何も入れていません。
rails g model user【2】マイグレーションファイルを記述する。
create_table "users", id: false, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t| t.string "id", limit: 36, null: false, primary_key: true t.datetime "created_at", null: false t.datetime "updated_at", null: false endポイントは二つです。
デフォルトの
idをfalseにする。
create_table "users", id: false,の部分ですね。ここをfalseにしています。uuid用のカラムを追加
t.string "id", limit: 36, null: false, primary_key: trueの部分ですね。
primary_key: trueのオプションをつけているのがポイントです。こうすることで、このカラムがprimary keyにすることができます。【3】moduleからuuidを作成
この部分に関しましては、この記事から引用させていただきました?♂️
app/models/concerns/id_generator.rbにuuid生成用のモジュールを作成してください。app/models/concerns/id_generator.rbmodule IdGenerator def self.included(klass) klass.before_create :fill_id end def fill_id self.id = loop do uuid = SecureRandom.uuid break uuid unless self.class.exists?(id: uuid) end end end順番に解説していきます。
self.included(klass)def self.included(klass) klass.before_create :fill_id endこのモジュールがインクルードされたタイミングで対象のクラスを引数にしてこのメソッドが呼び出されます
引用元:公式
つまり、このモジュールがインクルードされたタイミングで該当モデルで
before_create :fill_idが呼び出されます。fill_id
def fill_id self.id = loop do uuid = SecureRandom.uuid break uuid unless self.class.exists?(id: uuid) end end簡単にいうと、該当モデルの
idに対して、uuidを重複しないように設定します。【4】Userモデルでmoduleをincludeする。
app/models/user.rbで先ほどのmoduleをincludeしてください。app/models/user.rbclass User < ApplicationRecord include IdGenerator endこうすることにより、
before_createのタイミングでfill_idにより、uuidを設定することができます。最後に
以上です。これでPrimaryキーをUUIDとして設定することができると思います。
とはいえ、UUIDにはメリデリがあるので考慮してから採用するようにしてください。
ではでは✌️
- 投稿日:2020-12-06T17:48:35+09:00
第5回
- 投稿日:2020-12-06T17:47:43+09:00
第5回
- 投稿日:2020-12-06T17:38:21+09:00
Rails ラジオボタンの複数情報を保存する方法
Rails ラジオボタンの複数情報を保存する方法
環境
Ruby:2.6.5
Rails:6.0.3.
記述理由
探せど探し方もわからず2日間彷徨ったため、忘備録、戒めも踏まえて記述する
基本的な知識を踏まえて、今後の理解に務める。こうした方がいいなどのご指摘があり、教えていいよという稀有な方がございましたら、なんなりとお願いします。
①HTML側:複数チェックの情報を格納して送付する記述
index.html.erbまず form_withの記述の方法 <%= form_with(model: @company_type,url: companies_types_path(@company_type), method: :post,local: true) do |f| %> 中略 繰り返し表示させるための記述の方法 <div class="tab-pane fade show active" id="list-doboku" role="tabpanel" aria-labelledby="list-doboku-list"> <% industry_type = ["足場工事","舗装工事","しゆんせつ工事","石工事","造園工事","土木工事"] %> <% industry_type.each do |q| %><br> <%= f.check_box :industry_type , {multiple: true},q,nil %> <%= f.label :industry_type, q %> <% end %> </div> 中略 form_withを送付するための方法 <div class="text-center mb-5 col-6"> <%= f.submit "記録する" ,class:"btn btn-block send-button tx-tfm" %> </div> <% end %>①-2:HTML側:このように表示することができました
②controller側:複数チェックの情報を受け取り保存する記述
モデルs.controller.rbdef create @company_type = CompanyType.new(company_type_params) if @company_type.valid? @company_type.save redirect_to companies_types_path else render :index end end private def company_type_params params.require(:company_type).permit(:industry_type =>[]).merge(company_detail_id: current_user.id) end②-2:DB側:このように保存することができました
反省
探し方も悪かったと思いますが、つまづく人が少ないから探せなかったのかもしれません。
Qiita記事も初投稿、まだまだ勉強することはあると自分を勇気づけて次のエラーに取り掛かります。
圧倒的知識不足による問題の気がしますが、書いてみないことには分からないので投稿しました。
- 投稿日:2020-12-06T17:26:34+09:00
Rubyで小数点を使った計算をしたい時にはto_fメソッドを使う
ruby 2.7.0についての記事です
- to_f 文字列を 10 進数表現と解釈して、浮動小数点数 Float に変換する
公式ドキュメント(Stringクラスto_f)"10".to_f # => 10.0 "8".to_f / 100 #=> 0.08
- 投稿日:2020-12-06T16:28:22+09:00
【Rails Google Map】ストリートビュー(Street View)を静的に表示させるには
【Rails Google Map】ストリートビュー(Street View)を静的に表示させるには
この記事でできるようになること
以下の画像のように、自分のアプリ内に場所やお店のストリートビューを静的に表示できるようになります
ステップ
・GCPでStreet View static APIを追加
・認証用コードをマップの表示をしているViewに記述
・画像表示のコードを記述GCPでStreet View static APIを追加
GCPのコンソールに移動して頂いて、
APIとサービス>認証情報からご自分のAPI Keyをご選択ください!
認証用コードをマップの表示をしているViewに記述
Google Mapのストリートビューは以下のリンクにて取得できます
https://maps.googleapis.com/maps/api/streetview?size=640x480(←任意のサイズでOK)&heading=180&fov=120&location=緯度の値,経度の値&sensor=true&key=ご自身のAPIKeyheadingのパラメーターは、方向を決定します。0~360が指定可能。0は北、90は東、180は南、270は西を指します。
fovのパラメーターは、水平方向の視野を決定します。0~120が指定可能。120を指定すると広い範囲の画像が取得できます。
pitchのパラメーターは、カメラ角度(上向き下向き)を決定します。90~-90が指定可能。90は上向き、-90は下向きです。
引用元:https://maps.multisoup.co.jp/blog/1773/画像表示のコードを記述
Railsで導入する例としては、
addressカラムに住所の投稿を格納しているとき、index.html.erb<% @places.each do |place| %> <% results=Geocoder.search(place.address) %> <% if results.present? %> <% @latlng=results.first.coordinates %> <%= image_tag "https://maps.googleapis.com/maps/api/streetview?size=640x480&heading=180&fov=120&location=#{@latlng[0]},#{@latlng[1]}&sensor=true&key=ご自身のAPI Key" %>'のようなコードで実現できますね
GeocoderのGemの導入はしておいてくださいね?♂️うまくいかないとか、わからないなどあればいつでも
などで、ご連絡いただければ幸いです?♂️
- 投稿日:2020-12-06T16:18:06+09:00
【Ruby】様々な条件分岐について①(ifの使い方)
条件分岐について
条件分岐とは、自分が設定した条件について、値が当てはまっているか(真)そうでないか(偽)を判断し、その結果に応じた出力を呼び出すことができる方法のことです。
使用することが多いので、Rubyの勉強を始めたばかりの方はぜひ読んでみてくださいね!【内容】
・基本となるifの使い方
・ifを一行でまとめる方法
・条件が複数ある時のifの使い方【読んで欲しい人】
・条件分岐(if)をマスターしたい方
・Ruby初学者の方ifの使い方
ifを用いた条件式について解説します。ある特定の条件があり、その条件に当てはまる場合と当てはまらない場合で出力を変更したいときに使用します。
基本となるifの使い方
条件式が1つの場合if 条件式 条件式に該当する(真)ときの出力 else(条件式以外の場合) 条件式に該当しない(偽)であるときの出力 end実際に例文でも見てみましょう。
例文1age = 21 if age >= 20 puts "私は成人です。" else puts "私は未成年です。" end例文1:出力結果私は成人です。このように、
age = 21と定義されているので、ifの条件式に対しては(真)となり、「私は成人です」という値が返ってきます。もしage = 18など、ageの値が20未満であれば、条件式に対して(偽)となるので、「私は未成年です」という値が返ってくることになります。ifを一行でまとめる方法
実はこのif文をもう少しスマートに記載することができます。
例文2age = 12 puts age >= 20 ? "私は成人です。" : "私は未成年です。"例文2:出力結果私は未成年です。このように、三項演算子という手法を使えば、一行でコードを記載することもできます。
条件式? (真)の値 : (偽)の値
と記載することで、スマートに一行でまとめることができます。条件式の後に「?」を入れるのを忘れないようにしてくださいね。慣れてきたらこのように式を簡単にしてコードを書いてみましょう!条件が複数ある時のifの使い方
では、複数の条件式を使用したい場合はどのようにコードを書けば良いのでしょうか?
基本は下記のような書き方になります。条件式が複数ある場合if 条件式① 条件式①に該当する(真)ときの出力 elsif 条件式② 条件式②に該当する(真)ときの出力 elsif 条件式③ 条件式③に該当する(真)ときの出力 else どの条件式にも該当しない(偽)ときの出力 end実際に例文でも見てみましょう。
例文3hobby = "basketball" if hobby == "baseball" puts "私は野球が趣味です。" elsif hobby == "soccer" puts "私はサッカーが趣味です。" elsif hobby == "basketball" puts "私はバスケットボールが趣味です。" else puts "私は無趣味です。" end例文3:出力結果私はバスケットボールが趣味です。このように、例文2では、
hobby = "basketball"と定義されているので、3つ目の条件式hobby == "basketball"に当てはまることがわかります。複数の条件式が必要な場合は、上記のようにelsifで条件式を追加しましょう!くれぐれもelseifと書かないように注意してくださいね。今回はifの使い方について解説しました。本当は他の条件分岐についても書こうと思ったのですが、あまりにも内容が長くなってしまい、必要な情報を見落としてしまう可能性があるので、別の記事で解説しようと思います!
条件分岐は使用頻度が多いので、ぜひマスターしましょう!
- 投稿日:2020-12-06T15:56:31+09:00
【Rails】データが更新できない時は、バリデーションを確認
1. はじめに
アプリを作成している際に、Userテーブルに追加したカラムのデータが更新できずに困りました。
しかも、エラー文が出ないので何が原因なのかがなかなか分からずあたふたしていました。
最終的には原因を見つけられたのですが、解決に至るまでに思いの外、多くの時間を費やしてしまいました。
同じような現象で、時間を費やしてしまう人が少しでも減るように、ここに備忘録を残します。2. きっかけ
そもそもエラー文が出ていないのに、なぜデータが更新されていないことに気づいたかというと、
更新されたはずのデータを元に検索機能を実装しようとしたときに、
登録したはずのデータで検索結果が返ってくるはずが、なぜかデフォルト値で返ってきたので、
「あれ?おかしいな」と思ったのが始まりでした。
rails cでテーブルの中身を確認したらやっぱり更新されていない...。
コンソールを見ると、データが更新される段階でRollbackされていました。コンソール↳ app/controllers/users_controller.rb:11 (0.2ms) ROLLBACK3. 原因
結論から言うと、パスワードにかけていたバリデーションが原因でした。
ユーザーのデータを更新する際に、パスワードの入力が必要である設定になっていたのですが、
パスワードなしに、@user.updateをしようとしていたので、結果的にデータが更新されなかったようです。app/def show @user.update ( marriage: @post.marriage, childcare: @post.childcare, ) endと言うことで、バリデーションの設定を変更します。
ユーザー情報更新の場合、パスワードのバリデーションを外すように設定するのは、user.rb(変更前)validates :password, format: { with: password_format }, length: { in: 8..32 }ここに
on: :createを追加します。
こうすることでユーザー情報を登録する際のみにパスワードのバリデーションがかかります。user.rb(変更後)validates :password, format: { with: password_format }, length: { in: 8..32 }, on: :createユーザー情報更新の際に、パスワードのバリデーションがかからなくなったので、無事データが登録されるようになりました。
4. 最後に
原因は意外と単純でした。自分でバリデーションをかけておきながら忘れる始末。
灯台下暗しってやつですね...。今後は気をつけようと反省した次第です。
- 投稿日:2020-12-06T13:25:24+09:00
Ruby attr_accessorってなんぞぉ??
attr_accessorっなんすか?
rails チュートリアルのsessionあたり?トークン発行してのあたりで少し詰まったので
attr_accessorって何ぞってなったから調べたことをここに残しておこうと思う。
initialize クラスインスタンス生成 俗に言うnewされた際に1度だけ実行されるメソッド
Javaで言うコンストラクタと同じ意味っすねsample.rbdef initialize(name) # インスタンス変数@usernameに引数を代入 @name = name end本題
ゲッターとセッターを同時に定義してくれるメソッドです。
test.rbclass User def initialize(name) @name = name end end user = User.new('Alice') user.name # => 当然エラーですよねメソッド定義してないっすもいんね・・・・ #def name # #endtest2.rbclass User def initialize(name) @name = name end def name # ゲッターメソッド @name end def name=(name) # セッターメソッド @name = name end end user = User.new('Alice') user.name # => Alicegetter setter
getter,setterって言葉耳にしたことあるかもしれないですが
railsで書くとこんな感じです。
getter : attr_reader :name
setter : attr_writer :nametest3.rbclass User attr_reader :name # @name ゲッターメソッド attr_writer :name # @name セッターメソッド def initialize(name) @name = name end end user = User.new('Alice') user.name # => Alice実は更に短くなるんすよね・・・・
attr_accessor
test4.rbclass User attr_accessor :name def initialize(name) @name = name end end user = User.new('Alice') user.name # => Alice
- 投稿日:2020-12-06T12:32:37+09:00
LeetCodeをRubyで解く #2 [ Top Interview Questions, easy ]
LeetCodeをRubyで解く #1 [ Top Interview Questions, easy ]
#21 Merge Two Sorted Lists (Acceptance:54.8%)
問題
二つのソートされた連結リストが与えられるので、それらをマージし、新しいリストを返します。 Example 1: Input: l1 = [1,2,4], l2 = [1,3,4] Output: [1,1,2,3,4,4] Example 2: Input: l1 = [], l2 = [] Output: [] Example 3: Input: l1 = [], l2 = [0] Output: [0]はて、連結リストとは?となってしまい、手も足も出ず、解答を探しました。
調べた中でAcceptedされた解答例は以下の通りです。この例は再帰的でスマートな回答になっています。
結果: Accepted def merge_two_lists(l1, l2) return l1 || l2 if !l1 || !l2 if l1.val >= l2.val l2.next = self.merge_two_lists(l1, l2.next) return l2 else l1.next = self.merge_two_lists(l1.next, l2) return l1 end end # Runtime: 68 ms, Memory: 210.2 MBこの例は反復法です。読んでわかりやすい回答になっています。
結果: Accepted def merge_two_lists(l1, l2) l3 = ListNode.new(0) buf = l3 while l1 && l2 if l1.val <= l2.val l3.next = l1 l1 = l1.next else l3.next = l2 l2 = l2.next end l3 = l3.next end l3.next = l1 || l2 buf.next end # Runtime: 60 ms, Memory: 210.2 MB#26 Remove Duplicates from Sorted Array (Acceptance:45.9%)
問題
予め昇順にソートされた数値のリストを、リストを直接修正して重複を削除するという問題です。 Example 1: Input: nums = [1,1,2] Output: 2, nums = [1,2] Explanation: Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the returned length. Example 2: Input: nums = [0,0,1,1,1,2,2,3,3,4] Output: 5, nums = [0,1,2,3,4] Explanation: Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. It doesn't matter what values are set beyond the returned length.Exampleにごちゃごちゃと書いてありますが、numsの要素数をを出力し、numsは直接書き換えられていることが解答の仕方のようでした。
Rubyを使っている人はお気づきかと思いますが、Rubyのメソッドを使えば超簡単です。
まずは私の解答から。結果: Accepted def remove_duplicates(nums) nums.uniq! p nums.length end # Runtime: 52 ms, Memory: 210.9 MB調べた中にはほかにも、ちゃんと反復してdelete_atしているものも有りました。
結果: Accepted def remove_duplicates(nums) current_index = 0 while(current_index < nums.size) next_index = current_index + 1 if nums[next_index] == nums[current_index] nums.delete_at(next_index) else current_index = next_index end end puts nums.size end # Runtime: 72 ms, Memory: 211 MB#28 Implement strStr() (Acceptance:34.9%)
問題
haystack文字列の中でneedle文字列に一致する最初の位置を出力する問題 一致しなければ-1、haystackが空であれば0を返す。 分かりづらいですが例えばhaystack = "word", needle= "ord"だと1を返すことになります。 Example 1: Input: haystack = "hello", needle = "ll" Output: 2 Example 2: Input: haystack = "aaaaa", needle = "bba" Output: -1 Example 3: Input: haystack = "", needle = "" Output: 0頭の引き出しが足りず、愚直に書いてしまいました。
結果は時間切れ。5✕10^4までの文字数には単純に文字数分eachするのは厳しいようです。わかってはいますが…結果: Time Limit Exceeded def str_str(haystack, needle) return 0 unless needle.size > 0 haystack.split('').each_with_index do |word, idx| if needle[0] == word jadge = true (1..needle.length-1).each do |i| unless haystack[idx + i] == needle[i] jadge = false end end return idx if jadge end end -1 end # Runtime: N/A, Memory: N/A調べた中でAcceptedされた解答例は以下の通りです。
ループの回数をちゃんと制限かけてあげましょうということですね。結果: Accepted def str_str(haystack, needle) return 0 unless needle.size > 0 max_iterations = haystack.length - needle.length (0..max_iterations).each do |idx| if haystack[idx] == needle[0] same = true (1..needle.length - 1).each do |i| if haystack[idx + i] != needle[i] same = false end end return idx if same end end -1 end # Runtime: 68 ms, Memory: 210.5 MB#38 Count and Say (Acceptance:45.5%)
問題
文字列の中で連続した文字とその個数を並べ次の文字列にする。 それを与えられた回数ループさせる問題 Example 1: Input: n = 1 Output: "1" Explanation: This is the base case. Example 2: Input: n = 4 Output: "1211" Explanation: countAndSay(1) = "1" countAndSay(2) = say "1" = one 1 = "11" countAndSay(3) = say "11" = two 1's = "21" countAndSay(4) = say "21" = one 2 + one 1 = "12" + "11" = "1211" Example 3: Input: n = 5 Output: "111221" Explanation: countAndSay(1) = "1" countAndSay(2) = say "1" = one 1 = "11" countAndSay(3) = say "11" = two 1's = "21" countAndSay(4) = say "21" = one 2 + one 1 = "12" + "11" = "1211" countAndSay(5) = say "1211" = one 1 + one 2 + two 1 = "111221"愚直に書くしかないパターンなので、見事Acceptedになりました。
結果: Accepted def count_and_say(n) string = '1' (2..n).each do |idx| nxt = string.length > 2 ? string[1] : '' answer = '' count = 1 string.split('').each_with_index do |word, i| nxt = string[i+1] if word == nxt count += 1 end if word != nxt || i == string.length-1 answer += count.to_s + word count = 1 end end string = answer p string end string end # Runtime: 88 ms, Memory: 215 MBPythonであれば組み込みメソッド使えば簡単なようです。
classを使った例です。def count_and_say(n) return "1" if n == 1 return "11" if n == 2 result = "1" (2..n).each do result = read(result) end result end # "1211" => "111221" def read(str) result = "" str_characters = str.to_s.split("") buffer = [] str_characters.each_with_index do |character, index| if buffer.empty? buffer << character else if buffer.first == character buffer << character else result << read_unit(buffer) buffer = [character] end end end unless buffer.empty? result << read_unit(buffer) end result end # 1 => 11 # 2 => 12 # 11 => 21 # 111 => 31 def read_unit(buffer) "#{buffer.size}#{buffer.first}" end#53 Maximum Subarray (Acceptance:47.3%)
問題
整数の配列の中で、和が最も大きくなる部分的な配列(subarray)の和を求める問題 Example 1: Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6. Example 2: Input: nums = [1] Output: 1 Example 3: Input: nums = [0] Output: 0 Example 4: Input: nums = [-1] Output: -1 Example 5: Input: nums = [-2147483647] Output: -2147483647またもや愚直に書いてしまいました。
結果は時間切れ。1 <= nums.length <= 2 * 104だからです。わかってます。結果: Time Limit Exceeded def max_sub_array(nums) return nums[0] if nums.length == 1 max = nums[0] nums.each_with_index do |num, idx| sum = num nums[idx+1..nums.length-1].each do |n| sum += n max = sum if max < sum end max = num if num > max end max end # Runtime: N/A, Memory: N/A以下がAcceptedとなった解答例です。
全部足していって最大値を見つけるのではなく、「次の値との和」と「次の値」の大きい方をtempとし、これまでの最大値maxとtempの大きい方を取るんですね。結果: Accepted def max_sub_array(nums) return 0 if nums.nil? max = nums[0] temp = nums[0] nums[1..nums.length-1].each do |num| temp = [num, temp + num].max max = [max, temp].max end max end # Runtime: 76 ms, Memory: 210 MB問題の訳し方や解法等で問題があれば、お手数をおかけしますがコメントいただけると幸いです。
あと36問続きます…
- 投稿日:2020-12-06T11:41:59+09:00
MySQLが起動しない(Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2))
開発環境
- Ruby 2.5.8
- Rails 5.2.1
- MySQL 8.0.22
新規開発をしようと「rails db:create」をした時のこと・・・
ポートフォリオの大方の設計が出来上がってきたので、アプリの大枠だけでも作成しようと
rails newをして新規アプリを作成し、rails db:createでDBを作成しようとしたところ、エラーで止まった。rails db:create Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) Couldn't create 'myPF_development' database. Please check your configuration. rails aborted! Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)1週間ほど前に、実際の開発工程に入ってから躓くのは嫌だと思い、同じバージョンのRuby,Rails,MySQLで確りとテスト開発して確認したのになぜなのか…
1週間前は動いたmysql -u root -pを打っても、mysql -u root -p Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)となるばかりでまるで反応はなく…。またか…先週MySQL周りの設定で2日潰れたというのにまたなのか…MySQL君…、といった気持ちで調べてみるとやはりこの状況になる方は多いようで様々な記事が見つかりました。
その中でも、今回解決に導いてくれた記事を以下に貼っておきます。この記事のお陰で無事MySQLが動いてくれました。とても助かりました。■ 参考にした記事
mysqlが起動できない(Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2))解決はしましたが、今後もちょくちょくMySQL周りのエラーは起きそうな気がするので、Qiita記事を書く練習も兼ねてまとめておきます。上の記事と殆ど同内容にはなってしまいますがご容赦下さい。
mysql.sockファイルを作成する
エラー文にも書いてあるとおり、
mysql.sockというファイルを通してローカルのMySQLサーバーに接続しているらしいのですが、そのmysql.sockファイルがないと言われています。
そして厄介なことに、このファイルがなんらかの原因で消えることがあるらしいと。なので、以下のコマンドを通してmysql.sockファイルを作成します。sudo touch /tmp/mysql.sockMySQLの再起動をする
mysql.sockファイルを作成したら、MySQLを起動し直します。sudo mysql.server restart Starting MySQL ... SUCCESS!やった!
再度rails db:createしてみる
rails db:create Created database 'myPF_development' Created database 'myPF_test'いけた!よかった!
おわりに
これからもMySQL関連を触る時はお祈りしながらコマンドを打つことになりそうです…笑
先人のQiita記事に大感謝。
おまけ(個人的メモ)
MySQLの起動:mysql.server start
MySQLへの接続:mysql -u root -p
- 投稿日:2020-12-06T09:43:32+09:00
duplicate key value violates unique constraint "XXXXXX"の解決方法
ruby "2.6.4
rails", "~> 6.0.0"
postgressqlbin/rails db:dropbin/rails db:createbin/rails db:migratebin/rails db:seedあとは
ファイル名、英語のスペルが間違えていないか確認





































