Progate +α メモず【Ruby on Rails ④⑤】

# はじめに
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">気持ちよくコーディングできてるけど、こんな後からどんどん追加機能作ってきれいなままなの、すごい<br>Progateのカリキュラムの設計がいいのかな？と思ったけど、JSに置き換えて考えてみると、Ruby on Railsの力がなかなか大きい気がしてきた</p>&mdash; たま / SamuraiStats⚾ (@SamuraiStats) <a href="https://twitter.com/SamuraiStats/status/1746299427634213245?ref_src=twsrc%5Etfw">January 13, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Ruby on Railsの力を実感してきた今日この頃です。
MVCの分離とか、メソッドがちゃんと独立してることとか、結構すごくね？という。

# メモず
## 今更ながら、`.save` `.destroy`など
### Active Recordの永続化メソッド（Persistence Methods）
と呼ぶのが正しいっぽい。

>1. **`.save`**:
    - 新しいレコードをデータベースに保存するか、既存のレコードを更新します。
    - バリデーションが成功すれば`true`を、失敗すれば`false`を返します。
>2. **`.save!`**:
    - `.save`と同様ですが、バリデーションに失敗した場合に例外を発生させます。
>3. **`.create` / `.create!`**:
    - 新しいレコードをインスタンス化し、バリデーションを実行した後、データベースに保存します。
    - `.create!`はバリデーション失敗時に例外を発生させます。
>4. **`.update` / `.update!`**:
    - 一つまたは複数の属性を更新し、レコードをデータベースに保存します。
    - `.update!`はバリデーション失敗時に例外を発生させます。
>5. **`.destroy` / `.destroy!`**:
    - レコードをデータベースから削除します。
    - `.destroy!`は関連するオブジェクトの削除に失敗した場合に例外を発生させます。
>6. **`.delete` / `.delete_all`**:
    - `.delete`は単一のレコードを、`.delete_all`は条件に一致する複数のレコードを、バリデーションやコールバックを実行せずに削除します。

#### レコード
一列のデータのこと。`id`, `create_at`, `updete_at`, `content`などを持つひとかたまり。対義語：カラム
#### バリデーション
データが特定の条件やルールに適合していることを確認するプロセス。
- ユーザーのメールアドレスが有効な形式であるか
- パスワードが一定の長さ以上であるか
- 空白ではないか

などを確認すること。
## `link_to`の`post`バージョンの書き方
`link_to("削除", "/posts#{@post.id/destroy}, {method: "post"})`
第三引数で指定
### 第三引数のバリエーション

>1. **class:** CSSクラスを追加する。
>   ```ruby
>   link_to "プロフィール", profile_path, class: "btn btn-primary"
>   ```

>2. **id:** HTMLのID属性を設定する。
>   ```ruby
>   link_to "ログアウト", logout_path, id: "logout_link"
>   ```

>3. **data:** データ属性を設定する（JavaScriptで使用することが多い）。
>   ```ruby
>   link_to "保存", save_path, data: { confirm: "保存しますか？" }
>   ```

>4. **remote:** Ajaxリクエストを行うために`true`に設定する。
>   ```ruby
>   link_to "更に読む", more_posts_path, remote: true
>   ```

>5. **target:** リンクの開き方を指定する（例えば新しいタブで開く）。
>   ```ruby
>   link_to "外部サイト", "http://www.example.com", target: "_blank"
>   ````

### 雑記：Ajaxリクエスト
> Ajax（Asynchronous JavaScript and XML）リクエストは、ウェブページがサーバーとの間でデータを非同期的に交換するための手法です。Ajaxを使用すると、ページ全体を再読み込みせずに、ページの一部分のみを更新することができます。これにより、ユーザー体験が向上し、アプリケーションのパフォーマンスも改善されます。

>Ajaxリクエストの特徴は次のとおりです：
>1. **非同期性:** ユーザーがウェブページで操作を行うと、Ajaxリクエストはバックグラウンドでサーバーにデータを送信します。その間もユーザーはページで他の操作を続けることができます。  
>2. **小さなデータ交換:** Ajaxは必要なデータのみをサーバーと交換するため、トラフィックが減少し、応答時間が短縮されます。  
>3. **JavaScriptとの連携:** AjaxはJavaScriptを通じて実装され、ページの特定の部分を動的に更新するために使われます。  

>例えば、ソーシャルメディアサイトで「いいね！」ボタンをクリックすると、その情報がAjaxリクエストを介してサーバーに送信され、ページの「いいね！」カウントが更新されますが、ページ全体は再読み込みされません。これにより、スムーズでシームレスなユーザー体験が提供されます。
## `validates`：要素の検証 @modelファイル
### `validates`：バリデーションとは？
（繰り返しになるが）
データが特定の条件やルールに適合していることを確認するプロセス。
- ユーザーのメールアドレスが有効な形式であるか
- パスワードが一定の長さ以上であるか
- 空白ではないか

などを確認すること。
### 使い方・挙動
- `validates :content, {presence:true}`
この例では、`content`という名前のシンボルが`.save`されるとき、`presence`=空白ではないかチェックがされる。
- `validates`は`.save`メソッドが呼び出された時に、自動で実行される。
- `validates`に失敗すると、`@変数.errors.full_messages`にエラーメッセージが配列で生成される。
- `validates`はハッシュ
`validates :content, {presence: true, lingth: {...}}`
と、複数指定することが可能。

### 雑記：`validates`あれこれ
- （ほとんどのケースで推奨されないが）`validates: false`オプションで`.save`を行うことで、バリデーションをスキップしてレコードを保存することも可能。
- `presence`というのは「出席・存在」を意味する英単語
### `varidates`オプションず

>1. **presence:** 値が存在し、空でないことを確認します。
>   ```ruby
>   validates :name, presence: true
>   ```

>2. **length:** 文字列の長さに制限を設けます。`minimum`、`maximum`、`in`、`is`などのオプションを指定できます。
>   ```ruby
>   validates :password, length: { minimum: 6 }
>   ```

>3. **numericality:** 数値であることを確認します。`only_integer`、`greater_than`、`less_than`などのオプションがあります。
>   ```ruby
>   validates :age, numericality: { only_integer: true, greater_than: 0 }
>   ```

>4. **uniqueness:** 値がユニーク（一意）であることを確認します。同じ値がデータベース内に他に存在しないことを保証します。
>   ```ruby
>   validates :email, uniqueness: true
>   ```

>5. **format:** 指定された形式（正規表現）に合致することを確認します。
>   ```ruby
>   validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
>   ```

>6. **inclusion:** 値が指定されたセットの中に含まれることを確認します。
>   ```ruby
>   validates :status, inclusion: { in: %w[active inactive] }
>   ```

>7. **exclusion:** 値が指定されたセットに含まれないことを確認します。
>   ```ruby
>   validates :username, exclusion: { in: %w[admin superuser] }
>   ```

>8. **confirmation:** 通常、パスワードの確認などに使われ、二つのフィールドの値が一致することを確認します（例: `password` と `password_confirmation`）。
>   ```ruby
>   validates :password, confirmation: true
>   ```

## @post.contentと、@post[:content]の違いは？
基本的には同じ！！！！
```rb
@post.content = params[:content]
@post.save
```
```rb
@post[:content] = params[:content]
@post.save
```
この２つは同じ挙動をする。
ただし、カスタムセッター / ゲッターを使用する場合は別。
```rb
class Post < ApplicationRecord
  # content 属性に対するカスタムセッターメソッド
  def content=(value)
    self[:content] = value.strip # 入力値の前後の空白を削除
  end
end
```
>この場合、`@post.content = " こんにちは "` とすると、`content=` メソッドが呼ばれ、文字列の前後の空白が削除されてから `@post[:content]` に代入されます。しかし、直接 `@post[:content] = " こんにちは "` とした場合、カスタムセッターメソッドは呼ばれず、空白はそのまま保存されます。

## `render`と`redirect_to`の使い分け
`redirect_to`
- 他のページ（URL）に飛ばす。
- 引数はURL（`"/posts/index"`）
- データがリセットされる。
`render`
- 今のページでビューを変える（レンダリングする）。
- 引数はビュー（`"edit"`や`"posts/edit"）
- データや状態を保持する。
#### 例
- データ送信後：`redirect_to`
  そのページでできることはもうないので、別のページ（ホームページなど）に飛ばす。
- ページへのアクセス権限がない場合
  そのページでできることはないので、別のページ（ホームページなど）に飛ばす。
- アンケート・ログインなどのバリデーションエラー：`render`
`redirect_to`を使用すると入力データが消失し、空の（初期値の）ページが表示されてしまう。
- いいね！のリアルタイム表示：`render`
  `redirect_to`を使用すると、いいねを押すたびにページがロードされる、非常に使いにくいページになってしまう。

## `flash`：１度だけ表示されるメッセージ
`flash`はRuby on Railsで「デフォルトで」用意されているオブジェクト。
リクエスト間で短期間のメッセージを保存するために使われる。
⇒簡単に言うと「一時的なメッセージをビューでもコントローラでも使えるよ」。
### 使い方・挙動
- `flash[:notice]`もしくは`flash.notice`でアクセス可能（なはず）。
ビューでもコントローラでもアクセス可能。
- 次のリクエストが完了したときに、Railsによって自動的にクリアされる。
「次のリクエストが完了」とは、HTTPリクエストが完全に処理され、レスポンスをユーザーに送り返したタイミング。
## 雑記：失敗する変数の宣言
完全に雑記ですが。一応`flash`の宣言から触発を受けた内容です。
`var`は変数のこと。以下でやろうとしていることは`user = {:name => "tama"}`を抽象化したものです。
```rb
# varは宣言されていない前提
var[:key] = "value" # エラー。nilへのアクセス
```
↑ ダメなんですよね。エラーで止まっちゃう。
```rb
# varは宣言されていない前提
var = {:key => "value"} # 成功する
```
↑ これは成功する。

ちなみに、2つとも`var`が宣言されていればエラーになりません。
### なぜ？
```rb
# varは宣言されていない前提
var[:key] = "value" # エラー。nilへのアクセス
```
これは、`var`がまだ無いのに、その中に`:key`があるはずだ！って言ってるんですね。
（Railsはそう解釈する）
よって、まだないもの=`nil`の中身にアクセスできませんよ！っていうエラーを返す。
```rb
# varは宣言されていない前提
var = {:key => "value"} # 成功する
```
一方こちらは、最初に`var`ってまだ無いよね？だから作るね！って解釈されます。
そのあとに値を入れているので、正常に動作するわけですね。
### でも、`flash`のときは`flash[:key]`って書いたよ！！
そう。その通りです。
つまり、`flash`は事前に（隠れて）用意されているわけです。
だからいきなり`flash[:key]`と書いてもエラーにならない。
でも、他の変数は事前に用意されてないから、ちゃんと用意してから`var[:key]`って書こうね。という話でした（失敗談）。
# 終わりに
シンプル楽しめてて楽しいです（）
明日はユーザー登録！！！楽しみ！！！