あしあと

明日の自分への情報発信

Railsの学習(5日目)

はい

 

今回の目標

f:id:keropp1234:20200120081723p:plain

 

 まずはユーザーのデータを保存できるようにユーザーテーブルとユーザーモデルを作っていく。

そのためにrails consoleで「rails g model User name:string amail:string」と打ち込めば作成できる。stringというのは短文という意味で、Userというモデル名にnameとemailというカラムに短い文字列データがそれぞれ入りますよ、というイメージ

f:id:keropp1234:20200120081835p:plain

 

rails consoleでユーザーデータを保存してみる

user = User.new()で名前とメールアドレスを入力して、保存。idと作成日は自動的に保存される。

f:id:keropp1234:20200120083740p:plain


バリデーションを追加し、名前とメールアドレスが空でも登録できないようにする。

以下の図のように「validates :email,{uniqueness: true}」(唯一の、独自の)を指定することでチェックすることができる。前にやった投稿内容のときはpresence:trueだったな。一つのvalidatesで複数の内容を指定できるので、空のカラムと重複したカラムを弾くには「validates:email,{uniqueness: true, presence: true}」とすれば良い。

f:id:keropp1234:20200120084132p:plain

 

ユーザー一覧ページを作る。

そのためにuserコントローラとuserアクションを作り、データベースからデータを取得して全ユーザーが表示されるようにする。

f:id:keropp1234:20200120090242p:plain

 

ユーザー詳細ページのURLには「localhost:3000/users/1」のように、ユーザーデータのidを含めるようにする。また、下の図のように、ユーザー一覧ページのユーザー名から詳細ページに飛べるようにリンクに設定する。

f:id:keropp1234:20200120091543p:plain

 

ユーザーの新規登録〜ユーザーデータの保存〜

フォームに送信された値を送信するために、名前とメールアドレスそれぞれにname属性を指定する。name属性の名前がハッシュ呼び出しのキーになるため、分かりやすいネーミングをすること。

f:id:keropp1234:20200120103522p:plain

 

新規登録に失敗したときにエラーメッセージと前回の内容を維持したまま表示できるようにする。

<input>タグでは、value属性の値が初期値にな流ため。value属性に値を指定すると右の図のようにフォームに初めから値が入力された状態で表示できる。

f:id:keropp1234:20200120104725p:plain

 

inputの中の初期値をRubyのコードから引っ張ってくるには<%=%>と@と""を用いてvalueに代入する。

f:id:keropp1234:20200120104806p:plain

 

アカウント編集ページではユーザーが登録したデータを初期値にしたい。そのため、ユーザー編集ページのURLには「localhost:3000/users/1/edit」のように、編集するユーザーのidを含め、ユーザー編集フォームには初期値を設定しておく
また、左の画像のようにユーザー詳細ページに編集ページへのリンクを用意しよう

f:id:keropp1234:20200120111203p:plain



データベースにファイル名を保存するカラムを作成する。

データベースを変更していくにはマイグレーションファイルを作成し、それをデータベースに反映させていく。ちなみに今回はマイグレーションファイルだけでいいので

rails consoleでは「rails g model migration」ではなく「rails g migration」で出力する。

ファイル名は自由に決められるが、先頭に日付が追加される。分かりやすい名前が良い。

f:id:keropp1234:20200120142538p:plain

 

今回作成されたマイグレーションファイルにはテーブルに変更を加えるための命令が書いてないので、以下のようにchangeメソッドに書く必要がある。

f:id:keropp1234:20200120143334p:plain

 

rails modelによって生成されてきたマイグレーションファイルにはchangeの中身が自動生成されていたため、特に変更なく使うことができていた。f:id:keropp1234:20200120143348p:plain

そこで今回は自分で書く必要がある。その場合、左の画像のように「add_colum :テーブル名, カラム名 , データ型」というコードを書く。書いたら右のようにrails db:migrateでデータベースに変更を反映する。これによりユーザーデータにimage_nameカラムが追加される。

f:id:keropp1234:20200120143555p:plain

 

初期画像(twitterでいう卵みたいなアレ)を用意する。

初期画像のファイル名がdefault_user.jpgなので、ユーザー登録時に、image_nameカラムの値が「default_user.jpg」になるようにする。そうすることで自動的に初期画像が反映される。createアクション内の@userアクション内でnewメソッドの引数としてimage_nameを指定すれば命令として成立する。

f:id:keropp1234:20200120144151p:plain

 

画像を表示するには今まで通りHTMLで表示する必要がある。これはディレクトリの概念そのもので、public/user_imagesフォルダに画像が入っているため、/user_images/ファイル名とすれば表示されるようになる。もちろん@userのようなrubyのコードを引っ張ってきているので、<%=%>で囲う必要がある。

f:id:keropp1234:20200120145549p:plain

 

ユーザー毎に画像選択できるようにする。

そうするためにはinputタグに「type="file"」を書くことで画像の選択が可能になる。また、name属性をimageにしておく。

f:id:keropp1234:20200120150707p:plain

 

画像の送信は特殊なので、form_tagに「{multipart: true}」をつける必要あり。

f:id:keropp1234:20200120150853p:plain

 

画像のアップロード

そのために、右図のようにupdateアクションでファイル名をデータベース保存し、画像ファイルをpublicフォルダに保存していく。

f:id:keropp1234:20200120151548p:plain

 

Rubyのコードで画像を扱うにはあらかじめ用意されている、fileクラスを用いる。

ファイルを作成するにはfileクラスのwriteメソッドを使う。つまり、左図のように「file.write("ファイルの場所,ファイルの中身")」とする。file.writeの場所はpublicを指定する。これによってHello Worldと書かれたテキストファイルが完成する。

f:id:keropp1234:20200120151905p:plain

 

画像の保存

流れはさっきと同じ。updateアクションでデータベースにファイル名を保存し、画像をpublicフォルダに保存する。

f:id:keropp1234:20200120152542p:plain

 

まずはnameやemailを更新した時と同じように、updateアクション内で@user.image_nameの値を上書きする。そして画像の名前をユーザーのid名として保存されるように、#{@user.id}.jpgとする。

f:id:keropp1234:20200120153648p:plain

 

画像ファルもnameやemailと同様にparams[:image]として受け取ることができる。この中には送信された画像の情報が入っているので、これを利用してpublicフォルダに保存されるようにしていく。

f:id:keropp1234:20200120153928p:plain



画像を保存するためには画像データを下に画像ファイルを作る必要がある。ファイルを作るにはFileクラスを使用するが、前回使ったFile.write  ではなく、File.binwriteをつかあって保存する。これはコンピュータが画像をbinaryで認識しているからだと思われる。図のように変数imageに対してreadメソッドを用いることで画像を読み込むことができる。

f:id:keropp1234:20200120154211p:plain

 

画像が保存されるのは画像が送信された時のみにするために、if文を用いて実行する(endを忘れないように!)。

f:id:keropp1234:20200120154615p:plain

 

ログインについて

ログインとは、サイトを操作しているユーザーが誰かを特定できる状態のこと。ログインすることにより、同じURLでもその人に合わせた表示をしたりできる。

f:id:keropp1234:20200120173941p:plain

 

ログインするためにはメールアドレスとパスワードをrailsに送ってデータベースと称号し、特定する必要がある。

f:id:keropp1234:20200120182312p:plain

ログインを作るときも、まずはrooting, action,viewを追加する。

今回は「localhost:3000/login」でlogin_formアクションを呼び出せるようにする。

f:id:keropp1234:20200120182601p:plain

 

作成したlogin_form.html.erbに<input tyoe="password">として属性をpasswordにすると、パスワードフォームで伏せ字表示ができる。

f:id:keropp1234:20200120182725p:plain

 

パスワードカラムの追加

rails consoleで「rails g migration add_password_to_users」と入力し、マイグレーションを変更する。そして新しく作られたmigrateファイルにchangeクラスを作り、その中に「add_column :テーブル名, :カラム名, :データ型」を書く。そして「rails db:migrate」を実行すると、データベースにpasswordカラムが追加されている。

f:id:keropp1234:20200120203100p:plain

 

passwordにも必ず値が欲しいので、validationで有無の判定をしたい。その際はpresence:trueで良い。

f:id:keropp1234:20200120203436p:plain

 

フォームの値を送信できるようにする。

フォームから送信された値を受け取るためにrootingとactionを追加する。フォームの値を送信するため、postを使うことに注意。

f:id:keropp1234:20200120215200p:plain

 

form_tagメソッドを用いてlogin_form.html.erbにURLの送信先を指定(/login)する。

また入力された値がrails側に送信されるようにメールとパスワードの<input>タグにname属性をつけること。

f:id:keropp1234:20200120215231p:plain

 

/loginで一見二つのrootingがかぶってるように見えるが、getとpostで別のrootingなので問題はない。(link_toメソッドではデフォルトでgetのルーティングを探し、form_tagメソッドがデフォルトでpostのルーティングを探すようになっている。)

f:id:keropp1234:20200120215458p:plain

 

ログイン機能の流れ

f:id:keropp1234:20200120220142p:plain

 

ログインするユーザーを特定するにはフォームから入力された値をデータベースから参照し、一致するユーザーがいたらそのデータを主録し、@userに代入する

f:id:keropp1234:20200120220437p:plain

 

一致したユーザーがいた場合、フラッシュメッセージを表示するようにしてUserの投稿画面にリダイレクトし、いなかった場合は再度ログインフォーム入力画面にリダイレクトしてを表示するようにしているのが左の画像。

f:id:keropp1234:20200120220419p:plain