- 投稿日:2020-12-06T23:42:50+09:00
メッセージが投稿されたときに、一時的に「成功しました」的な表示をさせたい
- 投稿日:2020-12-06T23:03:02+09:00
sessionについて【アウトプット】
sessionについて自分用のアウトプットとして書いていく。
まずsessionとは何か
*変数session:サイト内でページを移動しても情報を維持し続けることができる。また、sessionで代入された値は、ブラウザに保存される。ブラウザとはGoogoleChromeとかである。どんな感じに書くのか。
session[:キー名] = 値【users.controller.rb】
def login
@users = User.find_by(...)
if @user
session[:user_id] = @user.idもし、@userがあるならsessionに@user.idを代入する。
これで@user.idの情報が保持され続ける。これがあればその人専用のサイトを見れたり、ログインできるのではないかなと個人的には考えている。
ログイン状態を解除したいときはログアウトができるようなリンクを作りsessionにnilを代入させてあげる。
こんな感じかな
session[キー名] = nil【users.controller.rb】
session[:user_id] = nil
end今日は久々に投稿したけどノートにはまとめてあるからアウトプットはできているはず
時間あるときに今日見たく書いていきたい。では以上
- 投稿日:2020-12-06T22:35:25+09:00
rails APIモード devise
手順だけ
ターミナルrails new devise_token_auth --api -d mysqlGemfile# トークンベースの認証を行うためのgem gem 'devise' gem 'devise_token_auth'ターミナル$ bundle install $ rake db:create $ rails g devise:install$ rails g devise_token_auth:install User auth$ rails g controller api/auth/registrationsapi/auth/registrations_conroller.rbmodule Api module Auth class RegistrationsController < DeviseTokenAuth::RegistrationsController private def sign_up_params params.permit(:first_name, :last_name, :email, :password, :password_confirmation) end def account_update_params params.permit(:first_name, :last_name, :email) end end end endconfig.ebRails.application.routes.draw do namespace :api do mount_devise_token_auth_for 'User', at: 'auth', controllers: { registrations: 'api/auth/registrations' } end endリクエストごとに token を新しくしない、変更頻度の設定を決める
config/inizialize/devise_token_auth.rb... config.change_headers_on_each_request = false config.token_lifespan = 1.month config.headers_names = {:'access-token' => 'access-token', :'client' => 'client', :'expiry' => 'expiry', :'uid' => 'uid', :'token-type' => 'token-type' } ...model/user.rbclass User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable include DeviseTokenAuth::Concerns::User end:trackableがあるとSessionのcreateがうまく行かないので一応削除。
postmanで確認してみる
新規登録
ログイン
- 投稿日:2020-12-06T22:33:43+09:00
Javascriptエラー問題集
事前準備
ターミナル上で下記コマンドを実行してcloneする。
git clone https://github.com/Shu-Hos/ajax_app_error.git cd chat-app_error bundle install yarn install rails db:create rails db:migrate問題1
新規投稿をしてもイベントが発火しません。
まずはこちらを解決しましょう!問題2
新規投稿をしようとすると添付画像のエラーが表示されます。
次はこちらの問題を解決してください。
ヒント
エラーの英文のしっかりと確認しましょう。
formText.value = "";に対してCannot set property value of nullと出ています。こちら翻訳するとnullのプロパティ値を設定できないという意味になります。こちらをヒントにプロパティ周りを確認してみると良さそうです。問題3
問題2のエラーが解決した後に再度新規投稿しても非同期ではUndefinedが出てしまい、一度リロードしないと投稿内容が反映されません。
こちらを修正して非同期で投稿ができるようにしましょう
ヒント
こちらエラーが出ずにUndefinedが出るということは、ajaxでレスポンスを受け取った後、新しい要素を作り出して表示するまでのプロセスのどこかに問題が潜んでいる可能性が高いです。問題4
残りはcheck機能のエラー問題です。
投稿をクリックしても色が変化せずに添付画像のエラーが出てしまいます。
こちら原因が2箇所あります。
ヒント
こちら404(Not found)エラーが発生していることから、Ajax送信時に問題が起きている可能性が高いです。
ajaxの送信内容やコントローラー周りを疑ってみましょう。
コントローラーでbinding.pryを使用してみるのも良いかも知れません。
問題5
エラーはでなくなりましたが投稿を何回クリックしても色が白に戻りません。
こちらがクリックする度に色がグレーと白が交互に変わるように修正してください。
ヒント
コンソールにエラーが出ていない+グレーには色が変わるという部分から
レスポンスを受けとった後に問題が潜んでいる可能性が高そうです。
色はどのように変化させているのかロジックを深く考えてみましょう。
お疲れさまです!!
何かご不明点とかあれば、今後ぜひ教えてください!
- 投稿日: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-06T19:04:31+09:00
ポートフォリオ作成記録 静的ページでの作成と自動テスト
generateで静的ページを作成
generateで静的ページ作成をしました。
また、コマンドの省略版の入力を知り、便利さを実感しました。
例:rails server = rails s、rails generate = rails g等また、destroyですでにgenerate/migrate/で生成されたものを取り消しを行い、
関連するファイルに追記されている内容も消せるのは便利すぎ!自動テスト!!!
現在の現場でもまだTDD(テスト駆動開発)が行われていないのが現状で、C#で一度私も勉強をした事があり、すごく興味がある分野です。
テスト記述と実行がすごく簡単に行えるのが、優しい。
ちなみに、流れが、まずはテスト(仕様通りに想定した状況で必ず動く)内容を記述して、一度実行して失敗させる(REDの状態)。
その後、そのテストコードを正常に動かすようにコードを記述して実行できる様にする(GREENの状態)。
さらに、動いたコードの処理記述で読みやすさを重視してのコードの書き直し(リファクター)の順で行ました。
私が働いている会社ではこの手段で開発を行うことを教えてもらってないので、今だに行っていないのが不思議です。
(馬鹿にする割には、毎回自動テストとテストケースの実行を手打ちのくせに(笑))ルーティング
クライアント(今回の場合はHPにアクセスする人のPC)からの要求(今回の場合は他のページを移動する)時に、
サーバーは、要求に応じて(ページごとに割り当てられているURLの末尾)プログラムで処理したHTML等のファイルを送り出す時のコントールする機能です。
クライアントとサーバーはあくまで、役割名なので互いがその役割を担うことを忘れずに!
(恥ずかしながら、私は専用のPC等のコンピュータしかその任された役割しかできないと勘違いしてました=シンクライアント)最後に
今回もあくまで、概要の内容でした。(まとめの内容もその内容で締め括られておりました。)
ただし、現在の私にとってはまだ点での知識であり、最初の頃に学んだ機会がありましたがその時より理解が深まったのが嬉しかったです。
あとは、個人的にはチュートリアルは難しいとか時間がかかるとかありますが最初からすんなり行くならこういった勉強は必要ありません。
また、学習後の理解を深める好意を行わずにただアプリを作りましただと業務で通じるのか不思議です。
このチュートリアルはあくまでもRailsの理解と使い方の基本とその関連知識を身に付けて欲しいとたった3章まで学習しただけでも感じる内容です。
私はこの学習で不明な点をメモしながらまずは1周して、復習の時間際に調べて内容の理解を他者に説明できる様に深めたいと思います。
また、ポートフォリオ作成時の意欲・開発速度・面接時に説明を受けた場合の対応などの能力向上の機会にしたいと思います。
- 投稿日: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: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-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-06T16:55:43+09:00
Rails エスケープ
Railsのエスケープとかについて、知識が曖昧だったので調べてみる
また後日、きちんと調べるXSS(クロスサイトスクリプティング)攻撃
まず、エスケープを知る前にこの攻撃方法を知っとかないといけない
XSS(クロスサイトスクリプティング:Cross Site Scripting)とは、
ユーザーに表示するコンテンツに悪意のあるスクリプト(主にJS)を
仕掛け、そのコンテンツを表示したユーザーにスクリプトを実行させることで
任意の操作をさせる攻撃のことWebアプリにおいて、動的にhtmlを出力する時、
そのデータをエスケープしていないと
悪意のあるhtmlやjavascriptが紛れ込むJSは、ブラウザ上で動作し
Cookieなども更新することができたりするのでセキュリティには気をつける例)クリックするとセッションIDが盗まれてしまう
任意のメッセージや処理が行われる などどう対策するか
ユーザーの入力した文字を出力する際に
自動的にHTMLをエスケープする必要があるデフォルトでエスケープさせる
エスケープとは
スクリプトを実行する対象となる文字列を
無害な文字に置き換えること& → & " → " < → &li; > → >エスケープしたくないとき
この自動的にHTMLをエスケープしてくれる仕組みは、便利だが
どんなときも文字列をエスケープしたいかというとそうではないこのようなときは、以下のメソッドを使用する
String#html_safe
html_safeメソッドそれ自体は何らエスケープを行なっていないという
安全であるとマーキングしているに過ぎないので注意するs = "".html_safe s.html_safe? # => trues = "<script>...</script>".html_safe s.html_safe? # => true s # => "<script>...</script>"あくまで、「s」にはまだスクリプトが埋め込まれている状態
特定の文字列に対してhtml_safeメソッドを呼び出す際には、
その文字列が本当に安全であることを確認する義務がある"<em>#{text}</em>".html_safe #=> ヘルパーを使う content_tag :em, text
- 安全でない文字列をエスケープ無しで出力しない
- ヘルパーでタグを出力する
sanitizeメソッド
ある程度タグをそのまま出したいものの、危険なタグは
出力しないようにしたいという場合に利用する出力できるタグをホワイトリスト形式で制限する
sanitizeはフィルタした結果のHTMLに対して
「String#html_safe」を実行して返すので
さらに、「raw」や「String#html_safe」を使う必要がない<% @comment = "<script>alert('Hello');<script> <%= sanitize @comment %> #生成されるHTML <div>alert('Hello');</div>参考記事
https://railsguides.jp/active_support_core_extensions.html
https://qiita.com/kamohicokamo/items/571c58f2d6738a7dfe6a
https://techracho.bpsinc.jp/hachi8833/2016_08_31/25326
https://qiita.com/sutetotanuki/items/5eda6bbb5532dd64529a#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0xss
https://railsguides.jp/security.html
https://www.websec-room.com/2013/03/14/567
https://blog.tamesuu.com/2019/10/14/459/
https://yuruli.info/rails5-using-escape-methods/
- 投稿日: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-06T16:14:12+09:00
【Rails】マイグレーション時にコメントを追加する
マイグレーション時にコメントを追加する方法
Rails 5からこの機能が標準で装備されたそうです。
それ以前ではgemを利用していたそうです。
追加したコメントはデータベース側に保存されます。コメントの付け方
マイグレーションファイルを生成されたら、
以下のような書式でコメントをマイグレーションファイルに追加します。class CreateProducts < ActiveRecord::Migration[6.0] def change create_table :products do |t| t.string :name, comment: '雑誌名' t.integer :z_code, null: false, comment: '雑誌コード' t.integer :num, null: false, comment: '取置冊数' t.string :release, null: false, comment: '発売日' t.references :customer, null: false, foreign_key: true t.timestamps end end endその後、rails db:migrateで完了です!
Sequel Proの「構造」から確認できます。コメントをつける意味
カラムにコメントをつける機能は「定義」を記録するって事が一番だと思います。
実際、6個程度のモデルしか作っていないのですが、
「name」カラム5つ「date」カラム3つも使っているのですよね・・・。
これからさらに追加で機能をつけていくとしたら、自身の備忘録としても意味がある機能だと思います。
ちなみに、コメントはあくまでメモとして残すものなので、
テーブルの動作的には何も影響はないそうです!参考にさせていただいたサイト様
https://techracho.bpsinc.jp/hachi8833/2017_02_23/36083
ありがとうございます!!
- 投稿日: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-06T13:19:11+09:00
[Rails] コントローラー作成方法
コントローラーの役割は「受け取ったリクエストを、モデル・ビューと連携しながらレスポンスとして返す」です。
作成
rails g controller コントローラー名rails g(generate)コマンドで、コントローラーと付随するファイルを一度に生成します。
命名規則は複数形を使用するです。
例えば、商品の情報を処理する場合はproductsと書きます。アクションを定義する
コントローラーは、リクエストに対応する処理を記述する場所です。実際に処理を用意しましょう。
7つのアクション
アクション名 役割
index 一覧表示ページを表示するリクエストに対応して動く
new 新規投稿ページを表示するリクエストに対応して動く
create データの投稿を行うリクエストに対応して動く
show 個別詳細ページを表示するリクエストに対応して動く
edit 投稿編集ページを表示するリクエストに対応して動く
update データの編集を行うリクエストに対応して動く
destroy データの削除を行うリクエストに対応して動くアクションとは、コントローラー内における処理のカテゴリーのことです。
コントローラーに、インスタンスメソッドとして定義します。インスタンスメソッドは下記のように書きます。
products_controller.rbclass ProductsController < ApplicationController def index # indexアクションを定義した end end削除
作成したファイル、もしくはコントローラー丸ごとを削除したい場合は下記のコマンドを実行します。
rails d ファイルの種類 削除するファイル名 rails d controller コントローラー名rails d(destroy)コマンドは、rails gで作成したファイル一式を全て削除するコマンドです。
- 投稿日: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-06T10:59:31+09:00
LaravelでRailsみたいなデバックがしたい。(スクール卒業生向け)
概要
巷にあふれる某スクール卒業生。
彼らがスクールで学ぶのはRuby on Railsなのだが他人との差別化を図る上でLaravelを用いてポートフォリオを作成する方々を散見する。彼らがスクールで学んだ、デバック方法は「binding.pry」ほぼ一択。
Laraveでよく見かけるデバック方法は,var_dump(); や dd(); でちょっとモヤモヤしてる方向けの記事になります。
結論
「binding.pry」みたいなことはLaravelでも出来る!!
eval(\Psy\sh());処理を止めたいところに「binding.pry」のように書いて、ターミナルで確認するだけです。
恐らく、この説明でスクール卒業生は使いこなせると思います。
「大金払ってRuby on Railsを学び、実務で使うのはLaravelなんですか?」
という意見もあると思うのですが、個人的には自分が卒業生でlaravelエンジニアというのもあり応援したい気持ちです。
- 投稿日: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あとは
ファイル名、英語のスペルが間違えていないか確認
- 投稿日:2020-12-06T09:01:21+09:00
Railsで検索機能を導入してみた
はじめに
RailsでWebサービスを作っていく際、データベース内を検索する機能をつくるのに一工夫が必要でした。
そこで、どのようにして検索機能を搭載したかを記していきます。環境
MacOS Catalina 10.15.7
Rails 5.2.4.4手順
ヘッダー部分に検索機能のバーを搭載していきます。
header.html.erb<div class="search-menu"> <%= form_with url: "/search", method: "get", local: true do |form| %> <%= form.search_field :keyword, placeholder: "作品・ユーザーを検索", value: @keyword, size: "30" %> <button id="search-btn" type="submit"><i class="fa fa-search"></i></button> <% end %> </div>上記のような検索窓が出来上がります。
「作品・ユーザーを検索」の文字列は好きなように変えましょう。
これで、大枠の部分は完成。
次は、中身の部分について解説していきます。search_controllerを作成し、以下のように記述します。
search_controller.rbclass SearchController < ApplicationController only: %i[show] def show @keyword = params[:keyword] || '' @keyword == '' ? (@digest = '全件の検索結果') : (@digest = "「#{@keyword}」の検索結果") @type = params[:type] || 'item' @items = Item.search(@keyword) @users = User.search(@keyword).where(admin: false) return (@results = @items) if @type == 'item' return (@results = @users) if @type == 'user' end end合わせて、検索結果の画面を作成していきます。
show.html.erb<div class="container"> <div class="search-digest"> <%= "#{@digest}:#{@results.count}件" %> <% if @keyword != "" %> <h6 class="search-no-option"><%= link_to "全件検索を行う", "/search" %></h6> <% end %> </div> <ul class="user-tabs"> <li class="<%= @type %>-" id="item"><%= link_to "作品(#{@items.count})", "/search?type=item&keyword=#{@keyword}", remote: true %></li> <li class="<%= @type %>-" id="user"><%= link_to "ユーザー(#{@users.count})", "/search?type=user&keyword=#{@keyword}", remote: true %></li> </ul> <div class="search-result"> <%= render partial: "search/#{@type}", collection: @results %> </div> </div>item.html.erb<div class="search-index-item"> <div class="search-show-item"> <%= link_to "/items/#{item.id}" do %> <%= image_tag item.image.url, alt: "作品の画像" %> <% end %> </div> <div class="search-item-wrapper"> <div class="search-item-title"> <%= link_to item.title, "/items/#{item.id}" %> </div> <div class="search-item-description"> <%= item.story %> </div> <%= render "shared/evaluation", item: item, division: false %> </div> </div>user.html.erb<div class="search-index-item"> <div class="search-show-item"> <div class="search-show-userimage"> <%= link_to "/users/#{user.id}", alt: "ユーザーの画像" do %> <%= image_tag user.image.url %> <% end %> </div> </div> <div class="search-item-wrapper search-user"> <div class="search-item-title"> <%= link_to(user.name, "/users/#{user.id}") %> </div> <div class="search-item-description"> </div> </div> </div>このような検索結果のタブが出来上がります。
(別途CSSを適用しています。)気をつけること
対象となるデータベースはそれぞれ違うと思いますので、適宜変更してください。
おわりに
Railsで検索結果を取得するための方法に関する記事が少なかったので、作成してみました。
検索機能をつけると、Webサービスとして骨格が出来上がってきた感じがするので、オススメです。
- 投稿日:2020-12-06T01:12:15+09:00
Docker開発環境でdocker-compose run web bundle exec erb2slim app/views/layouts/ --deletを実行したらエラーが出た
Docker開発環境で構築したアプリにSlimを導入したのでRails newした時にできた
.erbファイルをSlimに変更しようと思い、docker-compose run web bundle exec erb2slim app/views/layouts/ --deletを実行したところ下記のエラーがでたbundler: command not found: erb2slim Install missing gem executables with `bundle install`何をわけわからんこと言ってんねん!いれたやろがい!!!ってキレそうになりながら冷静になってみるとDockerのビルド?をしていないことに気づいたので下記を実行
docker-compose up --build
無事にDockerが起動したらDockerをもう一度止めて、
docker-compose run web bundle exec erb2slim app/views/layouts/ --deletを実行!!そしたら無事にerbファイルがSlimに置き換わっていた!!やったぜ!!!
Dockerで開発環境を作ってるので、Dockerにしっかり更新したよ〜!っていう旨を伝えなくちゃいけないっぽいわね。勉強不足であってるかわからんけど、そんな感じでやったらとりあえずできたのでヨシ!ということでひとつ
おわり!!!!!!
































