あしあと

明日の自分への情報発信

Rails(progate)の学習(8日目)とRailsチュートリアルの学習(1日目)

今日でprogateのrails終わりだあああああああ!!!

 

今日の目標

railsのパスワードの暗号化を学ぶ

ログインパスワードは今のままではデータベースに普通の文字列として保存されており、万が一見られたり盗まれたとき、いとも簡単にパスワードがわかってしまう。

f:id:keropp1234:20200123065900p:plain

続きを読む

Railsの学習(7日目)

7日目

 

いいね機能を搭載する

 

ユーザーがいいねした投稿ページを作る。

「どのユーザー」が「どの投稿」をいいねしたかを記録するために、「user_id」と「post_id」の二つのカラムを持つ「likesテーブル」を作成する。

f:id:keropp1234:20200122070724p:plain

 

rails g model を用いてマイグレーションファイルを作成し、準備ができたらrails db :migrateでデータベースに変更を反映させる。

f:id:keropp1234:20200122070812p:plain

 

いいねのデータはuser_idとpost_idの両方がないといけないので、バリデーションをかけておく。処理はpresence: trueで良い。

f:id:keropp1234:20200122070817p:plain

 

ログインしているユーザーがその投稿にいいねをしたか表示する。逆にいいねをしていなかったら、いいねをしていないと表示するようにする。

 

そのためにはログインしているユーザーがその投稿にいいねした投稿が存在するかどうか、ログインしているuser_idとpost_idが合致しているデータを、likesテーブルからfind_byを用いて探す必要がある。これをif文で書くことで、いいねしているかしていないかの条件分岐をさせる。

f:id:keropp1234:20200122175113p:plain

 

いいねボタンの準備

ここからいいねしたり、いいねを取り消したりできるようにする。まずはlikesコントローラを作成してLikeデータを作成するためのアクションを作成する。

今までコントローラは「rails g controller」コマンドで自動生成してきた。コマンドを用いるとビューファイルも自動生成されるが今回はビューファイルは必要ないので、今回はコントローラファイルを手動で作成する。

作り方としてはcontrollerフォルダに「likes_controller.rb」を作成することで作成される。

f:id:keropp1234:20200122180423p:plain

 

作成したコントローラに新たにLikeデータを作成するためにcreateアクションを作成する。createはデータベースにデータを作成するアクションなので、postで定義する。

今回はURLの部分は「どの投稿をいいねしたか」という情報を送信するために、「likes/:post_id/create」する。

f:id:keropp1234:20200122180549p:plain

 

これで作ったcreateアクションの中身を完成させ、そのアクションへのリンクを「いいね!」ボタンとして投稿詳細ページに表示させる。

createアクション内では新たにデータを作成後、投稿詳細ページへリダイレクトするようにする。user_idは現在ログイン中のユーザー、post_idは開いた投稿記事に応じたidにする。

f:id:keropp1234:20200122181221p:plain

 

作成したcreateアクションへのリンク(/likes/#{@post.id}/create)をlink_toを用いて投稿詳細ページに追加する。今までは「いいね!していません」と表示していた部分を、「いいね!」するためのリンクに書き換える。つまり「いいねしていなければ、いいね!というリンクと機能を表示するようにする」ということ。

f:id:keropp1234:20200122181442p:plain

 

いいね取り消しボタンを作る

いいね取り消し機能を作るにはlikesコントローラにdestroyアクションを用意する。

destroyアクションでは受け取ったログイン中のidと投稿内容のidをもとに削除すべきlikeデータを受け取り、削除する。

f:id:keropp1234:20200122195909p:plain

 

destroyアクションへのリンクを投稿詳細ページに追加し、今までは「いいね!済み」と表示していた部分を、「いいね!」を取り消すためのリンクに書き換えます。

f:id:keropp1234:20200122195921p:plain

 

Font awesomeを使っていいねボタンをアイコンにかえる

font awesomeを利用するには<head>タグがひつようになる。あとはapplication.html.erbに<link>を作って埋め込んでいく。詳しいやり方は(HTML & CSS 学習コース 中級編

f:id:keropp1234:20200122201146p:plain

 

これはあくまで読み込みなので、ここから実際にアイコンに変えていく

左の図のようにHTMLを書き、show.htmlにリンクを埋め込んだが、link_toメソッド内にHTML要素を記述するとうまく反映されてくれない

f:id:keropp1234:20200122201541p:plain

この場合は<%= link_to("URL") do %>HTML要素<% end %>とすることで実行できる。

f:id:keropp1234:20200122201721p:plain

 

つまり2個上のハートマークを表示するコードを参考にしつつ、上の画像のやり方を応用すれば、下の画像の通りになる。要は実行したいHTML要素をlink_toメソッドで囲うということだ。

f:id:keropp1234:20200122201904p:plain

 

いいねの数を取得する。

いいねの数を数えるにはSQLでも用いたCOUNTメソッドを使う。これは配列の要素数を取得するメソッドだがデーブルのデータ数を取得するのにも役立つ。

f:id:keropp1234:20200122212657p:plain

 

いいねした投稿を表示する。

今回はユーザーに関するページを作成するのでlikeコントローラではなくusersコントローラにお気に入り投稿一覧ページを表示するためのlikesアクションを作っていく。

f:id:keropp1234:20200122213554p:plain



ルーティングのURL部分はshowアクションと同様に、どのユーザーに関する情報を表示するかを判断するために「users/:id/likes」これでこのURLでアクセスできるrootingを作成できた。そのユーザーがいいねしたページというニュアンスが伝わりやすいURLだねぇ。実際には[params:id]になると思われる。

 

f:id:keropp1234:20200122213621p:plain

 

いいね一覧のページを表示する。

viewページ用いるための変数をlikesアクション内で定義する。whereメソッドを用いてそのユーザーに関するデータをlikesテーブルから取得し、変数@likesに代入する。これでビューページで変数を使うことができる。

f:id:keropp1234:20200122214037p:plain

 

likesアクション内で定義した変数@userと@likesを用いて、ビューも完成させたい。各投稿を1つずつ表示するためには、@likesに対してeach文を用いて、likeに紐付いているpostを繰り返し表示させる。

f:id:keropp1234:20200122214054p:plain

 

Railsの学習(6日目)

ユーザーがいない場合の処理

登録されていない値でログインした場合、再度ログイン画面に戻したり、エラ〜メッセージを出したり、フォームに打ち込んだ内容を初期値として表示できるようにする。

 

エラーメッセージを表示するためには「find_byで検索したが見つからなかった」という結果を伝えるためのコードを書く。

f:id:keropp1234:20200121081556p:plain

 

続きを読む

Railsの学習(4日目)

rails4日目

 

削除機能を作る

ootingはpostから始める。URLから削除したい投稿を指定できるように、「posts/:id/destroy」とする。このURLにidを含める考え方は合理的で大事だね。

f:id:keropp1234:20200119064954p:plain

 

postとgetの違いとは?

違いは画像の通り。destroyは投稿データを削除し、更新するのでデータベースを変更していることになり、post rootingになる

f:id:keropp1234:20200119065150p:plain

 

destroyアクションのリンクを作る際、今まで通りに作るとpostアクションを探してしまう。

f:id:keropp1234:20200119065445p:plain

そのため、link_toの第3引数に「{method: "post"}」を追加することで、「post」として定義されているルーティングにマッチするようになる。

f:id:keropp1234:20200119065457p:plain

 

destroyアクション内で行う処理は以下のとおり

f:id:keropp1234:20200119065710p:plain

 

投稿の制限をする

空白の投稿を制限する。

f:id:keropp1234:20200119180739p:plain

 

不正な投稿内容が投稿されないようにチェックする仕組みをValidation(検証、実証、認可、妥当性)という。これに引っかかるとデータベースに保存がされなくなる。

f:id:keropp1234:20200119180958p:plain

 

Validationは図のようにモデルとして設定する。validates」を用いてカラム名と内容を指定します。図のように{presence: true}を用いることで、「そのカラムの値が存在するかどうか」をチェックすることができます。右の画像はvalidates(検証) :content(検証するカラム名), {presence(存在感):true}で空の投稿がないかどうか検証する、となっている。

f:id:keropp1234:20200119181205p:plain

 

validationの詳細な指定

validationでは値が存在しているか否かだけでなく、文字数も設定できる。

図のように「length」を用い、{maximum: 数値}を指定することで、最大文字数を設定することができます。下の画像では文字の長さ、という意味になる。

f:id:keropp1234:20200119181825p:plain

 

validationで検証する内容はハッシュとなっているため、図のようにコンマで区切ることで複数の内容を検証することができる。

f:id:keropp1234:20200119182118p:plain

 

 

validationに引っ掛かったらもう一度入力フォームに戻る処理を行う。これにはsaveメソッドに真偽値を用いることで、validationに引っ掛かったパターンと引っかからなかったパターンを想定することができる。

 

例えば保存に成功したパターンをtrue, 失敗したパターンをfalseとそれぞれ返すようにするとして、rails consoleで試すと以下のようになる。

f:id:keropp1234:20200119182549p:plain

 

バリデーションの結果で表示するページを変える。

例えば投稿成功なら投稿一覧のページへ、失敗なら再度投稿フォームへ、というふうに設定してみる。

f:id:keropp1234:20200119201634p:plain

 

投稿できなかったときは投稿編集ページに飛ぶ(リダイレクトする)ようにする。保存できたときは投稿一覧ページへ飛ぶようにする。これをif文で条件分岐することで成立させる。

f:id:keropp1234:20200119201707p:plain

 

直前の内容を表示したまま編集ページに戻る

そもそもなぜ投稿した内容が消えてしまうのか?それは

①updateアクションでは失敗したときにeditアクションに転送しており、編集画面にリダイレクトするようになっている。

②さらにeditアクションはデータベースから編集前のデータを取得している。

③フォームの初期値は②で取得したデータにになるよう指定されている。

f:id:keropp1234:20200119202546p:plain

 

そしてupdateアクションの中の「params[:content]」にはpost.contentに代入するための、直前の投稿内容が入っているため、これを編集画面で呼び出すようにすれば良い。

f:id:keropp1234:20200119203004p:plain

 

そこで、render(差し出す)メソッドを用いることでeditアクションを経由せず、直接編集画面に表示できるようになる。

差出先は、render("フォルダ名/ファイル名")のように表示したいビューを指定する。
renderメソッドを使うと、redirect_toメソッドを使った場合と違い、そのアクション内で定義した@変数をビューでそのまま使うことがでる。プログラムの命令がどのようなルートで実行されているか、柔軟で有機的に捉えないといけないね。

f:id:keropp1234:20200119203316p:plain

 

このままだとユーザーに分かりづらいので、エラ〜メッセージが出るようにする。

rails consoleで流れを見てみると、保存失敗前には@post.errors.full_messagesの中に空の配列が入っており、失敗後にのなかにエラ〜メッセージが入っているのがわかる。

f:id:keropp1234:20200120073346p:plain


それをedit.html.erbのフォームの上で、each文を用いてエラー文を1つずつ表示するようにする。

f:id:keropp1234:20200120073556p:plain

 

サクセスメッセージの表示

ページに一度だけ表示されるメッセージをフラッシュという。

Railsではフラッシュを表示するために、特殊な変数flashが用意されている。アクションで変数flash[:notice]に文字列を代入すると、flash[:notice]をビューで使うことができます。変数flashは1度表示された後に自動で削除されるようになっています。flashはいろいろな箇所で共通で使っていくのでapplication.html.erbで表示しましょう。

下の画像で言えば、if文があるので、もしセーブしたら、表示したい文字列をフラッシュとして表示する、という意味である。

f:id:keropp1234:20200120075058p:plain

 

 

Railsの学習(3日目)

はいrails3日目〜。

 

SNSへの投稿内容を編集する

投稿を編集するには、①編集したい投稿を取得し、②その投稿のcontentの値を上書きした後に、③データベースに保存する。
図のようにpost.content = "新しい値"とすることで、投稿のcontentの値を上書きすることができる。

 

f:id:keropp1234:20200118065355p:plain

 

編集データを保存すると作成日は初投稿のままだが更新日は自動で更新される。

f:id:keropp1234:20200118065543g:plain

続きを読む

Railsの学習(2日目)

今日も頑張ろう

 

自動生成されるidカラム

idカラムはデータベースにデータが保存されるときに自動で入れられる。

f:id:keropp1234:20200117070704g:plain

created_atカラムとupdated_atカラムも、データベースに保存された時刻が自動で入るようになっている。
updated_atは名前のとおりデータ更新した時にも時刻が更新される。つまりcontentカラム以外自動挿入である。

f:id:keropp1234:20200117070823g:plain

 

find_byメソッド〜データベースから特定のidのデータを取得する。〜

特定のidを取得するには「find_by」を使う。

名前のように「〜から見つけてくる」という意味になるので、図のように、「モデル名.find_by(カラム名: 値)」と見つけてくる場所を指定してあげることで、その値を持ったデータをデータベースから取得することができる。

f:id:keropp1234:20200117071537p:plain

 

投稿詳細ページを作る

ルーティングのURL部分に「:」を用いて「posts/:id」と指定することで、「/posts/1」でも「/posts/2」でもshowアクションにいくようにすることができる。
「posts/:id」と書くと「/posts/◯◯」のような全てのURLが該当する。

こうすることで同じようなコードの繰り返しをせずに済むようになる。

f:id:keropp1234:20200117180848p:plain

 

「posts/:id」というルーティングは「posts/index」より下に書かなければいけない。
ルーティングは合致するURLを上から順に探すため、「posts/index」よりも上に書くと、「posts/:id」が、「localhost:3000/posts/index」という「posts/index」と合致させるためのアクションと合致してしまう。

f:id:keropp1234:20200117181125p:plain

 

controllerのaction内ではrootingで設定したURLと:idの値を取得することができるが、その値はparamsという変数にハッシュとして入っている。(1を設定したら1が取得できるということ?)
そのため、params[:id]とすることで、その値を取得することができる。アクションファイル内設定したファイルをviewファイルでは使うことができないので、「@」付けてviewファイルに渡してあげるのを忘れないように。

f:id:keropp1234:20200117182048p:plain

 

showアクションで変数@postを定義し、idカラムの値がparams[:id]と等しい投稿をデータベースから取得して代入します(つまり下の画像で言えば id: params[:id])がそれである。テーブルのidはURLのidと同じということになる。)
@postをshow.html.erbで表示することで、各URLに対応した投稿のデータが表示されるようにしましょう!

f:id:keropp1234:20200117184713p:plain

 

詳細ページへのリンクを作成する。

f:id:keropp1234:20200117193654p:plain

 

入力フォームの作成

HTMLのコマンドである<textarea>タグや<input>タグを用いることで入力フォームを作成することができる。
送信ボタンにはtype="submit"と、value="投稿"を指定する。

f:id:keropp1234:20200117194656p:plain

 

投稿を保存する。

投稿データを保存するにはcreateアクション用意することでデータベースに保存できる。下の画像で言えばpostsデータを保存する場所をcreateしろと命令してるイメージだろうか。

f:id:keropp1234:20200117194944p:plain

 

createアクションのrooting

これまでアクションを作成するときは「get」を用いてきたが、投稿のアクションを作るには「post」を用意する必要がある。これはクラス名のPostには一切関係ない。「そういうもの」、である。

f:id:keropp1234:20200117195131p:plain

 

フォームの申請先を指定する。

「form_tag」を用いることでフォームに入力されたデータを保存することができる。form_tagは、「form_tag(送信先のURL) do」のように送信先のURLを指定する。

これにより、投稿ボタンを押すことで指定されたURL(この画像では/posts/create)にデータが保存される。

f:id:keropp1234:20200117195426p:plain

 

createアクションではビューを用意する代わりに、リダイレクトという、他のURLに転送する機能を用いる。

f:id:keropp1234:20200117204329p:plain

 

リダイレクトを実行するには「redirect_to("URL")」コマンドが必要になる。これにより指定したURLに転送することができる。

f:id:keropp1234:20200117204315p:plain


しかしこの状態ではリダイレクトはしていても、データベースへの保存はできていない。そこで、<textarea>タグにname属性を指定すると、入力データを送信することができるようになり、name属性の値をキーとしたハッシュがRails側に送られるようになる。

f:id:keropp1234:20200117204753p:plain

 

以下の図のように、Postインスタンスを作成する際にparams[:content]を用いる。そのPostインスタンスを保存することで投稿機能が完成する。

f:id:keropp1234:20200117223417p:plain

 

orderメソッド

orderメソッドを用いることで、投稿一覧を並び替えることができる
order(カラム名: 並び替えの順序)のように使います。並び替えの順序には、昇順(:asc)と降順(:desc)のどちらかを指定できる。
created_atを基準に降順(:desc)に並べ替えると、新しいものから順番に表示するようになる。この辺りはSQLと似ている。

f:id:keropp1234:20200117223912p:plain