Progate_Ruby on Rails5学習コース②

1・ユーザー機能

マイグレーションファイルを作成する「Rails g model〜」は
カラムを1行だけではなく複数行一度に作れる。

例:Rails g model Animal name:string age:integer

・バリデーション
重複ないか→ uniqueness :true

・<input>タグにRubyコードを使う
→””の中にRubyのコードを埋め込む ”<%=%>”

2・画像

画像をブラウザで表示させるにはデータベースに保存しておいたファイルを表示。
※画像ファイル自身はpublicフォルダに格納し、ファイル名はデータベースに保存


マイグレーションファイル

マイグレーションファイルのみを作成したい場合は
ターミナルで「Rails g migration ファイル名」
わかりやすいよう、何を変更するための
マイグレーションファイルかがわかるのが良い。

・テーブルの変更はchangeメソッドに内容を書く。
書き方:add_column :テーブル名 ,:カラム名 ,:データ型

(「Rails g model〜」の場合は、changeメソッドに自動生成される内容を
Rails db:migrate」でデータベースに反映していた)

・初めてユーザー登録した人に同じ画像を付与するには
ユーザー登録のためのアクション内にカラム名
画像の名前(例:image_name=”a.jpg”)を指定する。

・表示のためには<img>タグを使う。

・画像ファイル選択には<input>タグにtype="file"を追加。
・画像の送信にはform_tagに「{multipart:true}」を追加

画像ファイルの生成と保存
Rubyのコード「File」クラスの「write」メソッドを使う
使い方:File.write(ファイルのある場所, ファイルの中身)
画像の場合は「write」ではなく「binwrite」を使用する。
さらに、ファイルの中身は「read」を用いて画像データを取得(image.read)

・更新の仕方自体は他と同様に「上書き」する
・publicフォルダへの保存も他と同様「params[:image]」で受け取れる。

3・ログインとログアウト、ユーザー名表示、アクセス制限

●ログイン:誰がサイトを操作しているか判別できる状態
・パスワードフォーム:inputタグのtypeを「password」とすると伏字になる。
・デフォルト:link_to→getルーティング form_tag→postルーティングを探す

step1:ユーザーの特定
誰がサイトを操作しているかがわからないといけないため
ログインするユーザを特定する操作を書く。
※エラーメッセージはバリデーションでの失敗によるものではないので
自分で作成したメッセージを表示させる。

step2:ログイン
・session変数:ページを離れてもユーザー情報の保持ができる。
代入された値はブラウザに保存。
書き方:session[:キー値]=値

★今ログインしているユーザーの情報を表示させる
・application.html.erb
各アクションに対応したビューファイルは<%=yield%>部分に代入。
→application.html.erbは全てのアクションに呼び出されている。
 →アクション全てにログインしている
  ユーザーを表示させるコードを書かなければならなくなる

解消する方法:before_actionでアクションが呼び出される時に処理させる。
(共通のアクションなのでapplicationコントローラに)
書き方:before_action :共通処理させたいメソッド名

※before_actionはonlyを用いることで指定したアクションのみでメソッドを実行できる。
(書き方:before_action :authenticate_user,{only:[:アクション名1,:アクション名2]} )

なお、各コントローラはapplicationコントローラを継承しているため
継承元のメソッドを使うことができる。

・@変数で定義した変数は、同じクラスの異なるメソッド内で共通で使用できる

★ログイン制限
①ログインしていないユーザー、異なるユーザーの制限
ログインしているユーザーがいない、合っていない場合は制限をかける
→制限をしないとURLを直接入力するとアクセスできてしまう

制限の仕方:authenticate_user(ヘルパーメソッド)をコントローラの先頭に書く。
authenticate_user:ユーザーを認証する

②ログインしているユーザーに対する制限
・ログインユーザーは入れないページを制限
ログインユーザーを禁止する「forbid_login_user」メソッドを定義

・異なるユーザーの投稿などを編集できないようにする
ビュー:異なるユーザーの編集リンクが出ないようにする
→ログインユーザーとそのページのユーザーが一致している時だけにする

アクション:直接編集ページにログインしても編集できないようにする
ensure_correct_userメソッドを定義して
ログインしているユーザーと編集ページのユーザーの情報が
一致している場合だけ編集ページを表示させる。
(ensure_correct_user:正しいユーザーか確かめる)

・文字列は「.to_i」で数値に変換
paramsで取得できるのは文字列なので数値に変換。


●ログアウト
sessionに代入された値を削除する=空(nil)にする(代入する)

※getとpostの使い分けの基本
get→データベースを変更しない場合
post→データベースを変更する場合、sessionの値を変更する場合

4・投稿とユーザー、投稿の編集・削除

・どのユーザーがどのような投稿をしたか表示させる
→投稿とユーザーを紐付ける
インスタンスメソッドを用いて投稿に紐付くユーザーの情報を簡単に使えるようにする
インスタンスはmodelsの中)

・find_byは投稿に一致するデータを1件だけ
 whereであれば複数を取得できるため、一覧を表示させるなどの時はwhereを使う
 whereで取得したデータは配列に入る。

5・いいね機能

どのユーザーがどの投稿に「いいね」したかをデータで管理する
・いいねしたユーザー、いいねされた投稿のユーザーを管理
・ビューファイルを作る必要がないときは手動でコントローラを作成する

・HTML要素に対してlink_toメソッドを使うには<%=link_to (”URL”)do%>と書いて
最後に<%end%>をつけ、その間にHTMLコードを記述する
<%=link_to (”URL”)do%>
  HTMLコード
<%end%>
(通常のlink_toメソッドは<%=link_to("表示文字列","URL")%>)

・データの件数を取得する→countメソッド

6・パスワード

データベースには安全性の高いパスワードを保存しておく
→盗まれたり覗き見されても内容が分からない状態

●ハッシュ化
①Gemfileとgem
gem:RubyRailsを使う際によく使う機能のパッケージ化。
Gemfileはappフォルダ内にある。

gemのハッシュ化するgemである「bcrypt」をインストール
やり方:・Gemfileに「gem 'bcrypt'」と追加
    ・ターミナルで「bundle install」を実行
※特定のバージョンのgemをインストールしたい場合は
「gem 'gemの名前''gemのバージョン'」とすればいい

②has_secure_passwordメソッド
bcryptをインストールするとhas_secure_passwordメソッドが使えるようになる。

●パスワードを使うモデルにhas_secure_passwordを追加する。
→ユーザーが保存すると自動でパスワードのハッシュ化をしてくれる。

※パスワードが存在するかどうかも確認してくれるため、
 空の場合は保存が成功しないようにする
 バリデーション(presence: true)もいらない。

●has_secure_passwordメソッドはハッシュ化したパスワードを
「password_digest 」カラムに保存することになっているため、
カラムがなければ「Rails g migration〜」で用意する。

マイグレーションファイルは複数のカラムの変更も可能。
・カラムの削除をしたい場合は、「remove_column」を用いる。
使い方:remove_column :users,:address,:string
(カラムの追加は「add_column」、カラム名の変更は「rename_column」
カラム名の変更だけ、「rename_column :テーブル名,:変更前のカラム名,:変更後のカラム名
・最後にターミナルで「Rails db:migrate」を実行し反映するのを忘れずに。

●ハッシュ化されたパスワードはpasswordに通常通り値を代入して
has_secure_passwordにより代入されたパスワードがハッシュ化され
password_digestカラムに保存される。

●has_secure_passwordメソッドを使うと「authenticate」メソッドが使える。
渡された引数をハッシュ化してpassword_digestカラムの内容と一致するかを確認してくれる。
使い方:password_digestの内容.authenticate(入力された内容)
具体例:パスワードを入力フォームで受け取った場合
    @user.authenticate(params[:password])

気になること
・ヘルパーメソッド、Rails devise