rubyをこれから学ぶ人のために簡単なtipsを紹介していきます。
クラスメソッドとインスタンスメソッド
クラスメソッド.newでインスタンスを作り、
インスタンス.メソッドでその中のメソッドを呼び出す。
まずはモデルから作る
開発ではまずモデルが一番最初に作られる。
モデルはただのクラスだが、データベースと連携するクラスをrailsではモデルという。
rails g modelコマンド
初期データを入れる
seedを使うか、rails consoleで入れる。
seeds.rbにデータを書いて、rails db:seed コマンド
データの登録、更新、検索はどうする?
ActiverecordはSQLを触ることなくデータベースの操作ができる。
例えばrails cで
Book.allはselect * from books;と同じ
railsとDBはActiverecordとDBMSによって結び付けられている
allメソッドでデータをすべて取ってくる。
findメソッドでデータベースからデータを検索して取得する。
id=2
Book.find(id)
createメソッドでデータを登録する
Book.create(category:”家賃”,amount: 7)
updateメソッドでデータを更新する
book=Book.find(1)
book.update(amount: 31)
データの取得や登録はBook(クラス)に対して行う。
更新や保存はbook(インスタンス)に対して行う。
データベースのテーブル自体の操作
マイグレーション機能
rails g model ~でモデルとマイグレーションファイル作成
rails db:migrateでマイグレーションファイルをもとにテーブル作成
ウェブサーバ
ウェブサーバはブラウザからリクエストするとリクエストに応じたレスポンスを返すプログラム
ルーティング
ブラウザからのリクエストはURLとHTTPメソッドの2つのペア
メソッドの中でデータを取得するには
@books = Book.all
Bookはモデルを表すので大文字。
erbファイル
rubyのコードは<% %>で埋める。
<%= %>にすると実行した結果を表示する。
bootstrap
cssを書かなくてもある程度見た目をよくする
layouts/application.html.erbというファイルにcssやjsの読み込みを書く。
params[:id]の意味
ルーティングにかいた
get “/books/:id”, to : “books#show”, as: “book”
の:idに入った値をコントローラーの中ではparams[:id]で受け取れる。
リクエストに含まれる全パラーメータはこのparamsに格納される。
たくさんのデータがあるので、ストロングパラメータを使って登録に必要なデータのみを取り出す。
画面で入力したデータをbook_paramsに格納
book_params = params.require(:book).permit(:year,:month,:inout,:category,:amount)
#画面から入力したデータをもとにbookモデルを新しくインスタンス化
@book=Book.new(user_params)
データベースに保存
@book.save
@変数
メソッドやビューの間を横断して使える変数。
コントローラーからビューへデータを受渡しするときにつける記号
link_toメソッド
aタグによるリンクを作ってくれるメソッド。
book_path(book)というメソッドで、bookというインスタンスを渡すことで、自動的に
idを取り出してbook/2のようなURLを作る。
このようにhtmlを生成するメソッドをビューヘルパーと呼ぶ。
routingの順番
books/:idの:idはなんでもいいという意味なので、一番下にかかないと間違ったルーティングになる。
get,postの違い
getは情報の取得、URLがリクエスト内容全体を表す。
postは情報の送信、postデータを一緒に送信している。
バリデーション
rails検証機能
カラムごとに記述
データベースに保存するタイミングで検証をして、失敗すると
@book.saveがfalseを返す。
なので、ifを使って、失敗時と成功時で分岐できる。
render
表示するビューファイルを指示するメソッド。
通常、railsが自動的にアクションと同じ名前のビューファイルを表示している。
newメソッドならnew.html.erbに行くなど。
※実装はルーティング、コントローラー、ビューの順番でする。
_pathメソッド
routers.rbで定義したURLのニックネームに
コントローラーやerbファイルで_pathをつけると
URLを返すメソッドになる。
PATCHメソッド
httpメソッドの一つで、データ更新に関しては更新専用のpatchというHTTPメソッドを使う。
method:"patch"
ルーティングにニックネームをつける
get "/books/:id",to: "books#show",as:"book"
get "/books/:id",to: "books#update"
ニックネームを書いていない場合はすぐ上のニックネームを引きつぐ。
updateメソッド
saveとおなじくデータベースへ保存するメソッドなので、バリデーションのルール検証を行う。
railsはステートレスである
サーバーが自分たちのことを覚えているわけではなく、毎回新規のリクエストをサーバに向けて送っている。
これをステートレスという。
flash
次のリクエストまで情報を一時的に覚えている機能。
flashメッセージの実装で使われる。
実装は主に2か所。コントローラーでデータを登録。
flashに登録したデータを表示するビューの処理
flashとflash.nowの違い
flashは次のアクション終了までメッセージを残す。redirect_toと使う。
flash.nowは次のアクション起動で消える。renderと使う。
リファクタリング
見た目や機能を変化させずにコードをよりよくするもの
before_action :メソッド名
などで冗長なコードを削除することがそれにあたる
resourcesメソッド
自動でルーティングを生成する
アプリの機能1つごとに1行ずつrouters.rbに書いていくのは大変。
rails routesでrailsが認識するルーティングを書いてくれる。
books GET /books(:format) books#index
books :URLのニックネーム
/books :URL
(:format) :/books.htmlとしてもいいよよいう意味
books#index:books_controllerのindexアクション
resources :books と書くと下の7行のルーティングを自動で作る。
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
パーシャル
複数のビューファイルの共通部分を抜き出し、別ファイルとして保存して、ビューからパーシャル機能を
使って呼び出すことで同じコードを何度も書かなくてよくなる。
ファイル名は必ず_で始める。
呼び出し元は共通部分を削除して、変数を記入する。
<%= render partial: "form", locals:{type: "更新",book: @book,method: "patch"} %>
URLはリソースを表現する
リソースはデータのこと
/books/2というURLはidが2である家計簿データ
つまりURLとHTTPメソッドの組み合わせはデータと操作を表している。
このリソースと処理の組み合わせを表現したルーティングをRESTfullという。
詳しくは後述しますが、リクエストしてきた人物が、現在ログインしているかどうかは、セッション
という仕組みでRailsが認識できるようになります。
そこで、パスワードを安全に保存するために、bcryptという外部ライブラリを利用します。rubyでは
外部ライブラリ(ダウンロード&インストールして使うRubyの拡張機能)をgemと言います。
passwordを安全に保存するための設定
gem 'bcrypt', '~> 3.1.7’をうって
class User < ApplicationRecord
has_secure_password
end
ハッシュ化には4つ大きな特徴があります
不可逆であること
同じパスワードは常に同じ文字に変換される
一文字でも違うと全然違う文字に変換される
元のパスワードの候補が複数ある
ログインする仕組み
最初に行うのは、データベースからメールアドレスでユーザを検索することです。メールアドレスは
被らない(バリデーション)ので、1件も存在しないか、存在しても1件のみです。
1件もユーザが見つからない時は、その時点でログイン失敗です。
では、めでたく送信されてきたメールアドレスで検索し、ユーザが見つかったとします。
idで検索するにはfindを使っていましたが、id以外の特定のカラムで1件だけ検索する時はfind_byを使います。
user = User.find_by(email: params[:email])
次にパスワードのチェックをするのですが、フォームから送られてきたのは「パスワード」で、デー
タベースへ登録されているのはパスワードをハッシュ化した「パスワードダイジェスト」です。
has_secure_passwordのいいところは、ハッシュ化&比較を一つのメソッドでできることです
user.authenticate(params[:password])
これで比較ができます。このメソッドは一致すればユーザのインスタンスを、不一致であればfalseを返します。
render とredirectの違い
・render : controller → view・redirect_to : controller → URL → route → controller → view
redirect_toの方がちょっと遠回りしてますね。
renderがviewファイルを指定して、それを表示させるだけの処理に対してredirect_toはブラウザ上でHTTPリクエストを受けたのと同じ処理がされます。
ログイン機能
sessionコントローラーを使うことが多い
ログイン状態を維持するセッション
セッションとは、ブラウザ毎に情報を管理してくれる仕組みです。セッションを使い、「このブラウ
ザからリクエストを送ってくるユーザはログイン済みだ」と目印を付けておくことで、ログイン状態
を維持します。
def create
user = User.find_by(email: params[:email])
if user.present? && user.authenticate(params[:password])
flash[:notice] = "ログインしました"
session[:user_id] = user.id
redirect_to books_path
else
flash.now[:alert] = "failed"
render "new"
end
end
sessionというハッシュみたいなものに、データを入れているイメージで
privateの意味
他のファイルからアクセスできないメソッドを置いておく。
nullではなくnilを使う
rubyではnullの代わりにnilが使われるので注意
未ログイン時は強制的にログイン画面に行かせたい。
application_controllerに
def redirect_to_signin
redirect_to signin_path if session[:user_id].blank?
end
と書いて他のコントローラーにはbefore_action redirect_to_signin
とかけばいい。
まとめ
ブラウザからraisアプリへURLとHTTPメソッドの組み合わせでリクエスト送信
routers.rbでどのコントローラーのどのメソッドへ処理を飛ぶかを記載しているので、そのルールにより該当コントローラーに移動。
コントローラーではモデルを使ってデーターベースへアクセスして、画面に必要なデータを準備します。
ビューファイルを用意されたデータを使って描画し、erbファイルからhtmlファイルへ変換します。
完成したhtmlファイルをブラウザにレスポンスして返却して処理は完了します。