rails初心者のためのtips

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行ずつ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が２である家計簿データ
つまりURLとHTTPメソッドの組み合わせはデータと操作を表している。
このリソースと処理の組み合わせを表現したルーティングをRESTfullという。
詳しくは後述しますが、リクエストしてきた人物が、現在ログインしているかどうかは、セッション
という仕組みでRailsが認識できるようになります。

そこで、パスワードを安全に保存するために、bcryptという外部ライブラリを利用します。rubyでは
外部ライブラリ(ダウンロード&インストールして使うRubyの拡張機能)をgemと言います。

### passwordを安全に保存するための設定

gem 'bcrypt', '~> 3.1.7’をうって

```ruby
class User < ApplicationRecord
has_secure_password
end
```

ハッシュ化には4つ大きな特徴があります
不可逆であること
同じパスワードは常に同じ文字に変換される
一文字でも違うと全然違う文字に変換される
元のパスワードの候補が複数ある

### ログインする仕組み

最初に行うのは、データベースからメールアドレスでユーザを検索することです。メールアドレスは
被らない(バリデーション)ので、1件も存在しないか、存在しても1件のみです。
1件もユーザが見つからない時は、その時点でログイン失敗です。
では、めでたく送信されてきたメールアドレスで検索し、ユーザが見つかったとします。

idで検索するにはfindを使っていましたが、id以外の特定のカラムで1件だけ検索する時はfind_byを使います。

```ruby
user = User.find_by(email: params[:email])
```

次にパスワードのチェックをするのですが、フォームから送られてきたのは「パスワード」で、デー
タベースへ登録されているのはパスワードをハッシュ化した「パスワードダイジェスト」です。

has_secure_passwordのいいところは、ハッシュ化&比較を一つのメソッドでできることです

```ruby
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コントローラーを使うことが多い

### ログイン状態を維持するセッション

セッションとは、ブラウザ毎に情報を管理してくれる仕組みです。セッションを使い、「このブラウ
ザからリクエストを送ってくるユーザはログイン済みだ」と目印を付けておくことで、ログイン状態
を維持します。

```ruby
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に

```ruby
def redirect_to_signin
        redirect_to signin_path if session[:user_id].blank?
    end
```

と書いて他のコントローラーにはbefore_action redirect_to_signin

とかけばいい。

## まとめ
ブラウザからraisアプリへURLとHTTPメソッドの組み合わせでリクエスト送信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759966/b87d6fc8-9c5d-84d0-0044-6a760b274d3f.png)
routers.rbでどのコントローラーのどのメソッドへ処理を飛ぶかを記載しているので、そのルールにより該当コントローラーに移動。
コントローラーではモデルを使ってデーターベースへアクセスして、画面に必要なデータを準備します。
ビューファイルを用意されたデータを使って描画し、erbファイルからhtmlファイルへ変換します。
完成したhtmlファイルをブラウザにレスポンスして返却して処理は完了します。