備忘録：某スクールで使うRails Viewのチートシート（作成中）


##form_with

以下は、@bookを用いて例を示します。
form_withは、以下のように@bookを見て、submitした時のメソッドを自動で決めてくれる。

<details><summary>筆者つぶやき</summary>
入力フォームは、**部分テンプレートで作成しておけば、便利。**
edit画面でもnew画面でも流用できる。
form_withは、@bookの中身を見て判断してくれるからだ。
</details>

| @book | メソッド |
|:-:|:-:|
| @book=Book.new  | create  |
| @book=Book.find(params[:id])  | update  |


```erb:xxx.html.erb
<%= form_with model:@book,local:true do |f| %>

    <%= f.label :title %>
    <%= f.text_field :カラム名, class: 'form-control' %>

    <%= f.submit class: 'btn' %>

<% end %>
```
####form_with　追加オプション

#####テキストボックス関連

```erb:xxx.html.erb

 #入力ボックスの高さ調整　　
  #５行分の高さになる
<%= f.text_area  :カラム名,rows:'5' class: 'form-control' %>

 #入力ボックスの初期値
  #なにも打ち込まなければ「入力してください」となる
<%= f.text_area  :カラム名,placeholder: “入力してください” class: 'form-control' %>

```

#####ネストされているモデルをフォームに書く場合
以下では、例として、@book_commentが@bookにネストさている場合を示す。

<details><summary>筆者つぶやき</summary>
form_withをよく見てみると、URLを一切指定していない。（指定することも可能だが。）
つまり、「model:@book」の部分で判断して、URLを発行してくれていることになる。
ネストすれば、URLは"/book/3/book_comment"とかになる。
このことを分かってもらうために、
例えば@book_commentの投稿にも、@bookの存在を同時にform_withに教えてあげないといけないのか。
</details>

```erb:xxx.html.erb
<%= form_with(model:[@book, @book_comment], local: true) do |f| %>
```


#####radioボタン
```erb:
<label><%= f.radio_button :feeling, "good" %>s良い</label>
<label><%= f.radio_button :feeling, "numb" %>無感覚</label>
<label><%= f.radio_button :feeling, "bad" %>悪い</label>


<%= f.select :feeling, [["good","良い"],["numb","無感覚"],["bad","悪い"]] %>
```

##f.object

```erb:
<%= f.number_field :age %>
```
hidden_fieldは、paramsに格納されるときのキーを指定し、そこに入れたい値を格納する。
自由度がかなり聞いている。binding.pryでparamsを見れば、どうなってるかすぐ分かる。

```erb:
<%= f.hidden_field :user, :value => user.id %>
```

##link_to
主に、**show、destroy、edit**のリンクの雛形

```erb:xxx.html.erb



  #Destroy（確認メッセージ付き）
<%= link_to 'Destroy', book_path(@book), method: :delete, data: { confirm: '本当に消しますか？' }, class: "btn btn-sm btn-danger destroy_book_#{@book.id}"%>



```

##部分テンプレート

このviewファイルと同じ場所に部分テンプレートがあれば、'form'で良い
部分テンプレート内では、bookを使用する。末尾は@book=>bookに値を渡す作業。

```erb:

<%= render 'book/form', book: @book %>

```

##リダイレクト

```rb:
redirect_to book_path
redirect_to request.referer
```



##ストロングパラメータ

```rb:

private
def book_params
  params.require(:book).permit(:name, :price, :opinion)
end
```

##バリデーション

```rb:
validates :title, presence: true
```

##1対多関係の構築

```rb:
class User < ApplicationRecord
    has_many :posts, dependent: :destroy
end

class Post < ApplicationRecord
    belongs_to :user
end
```

##Each文とTable
以下例では、Bookの一覧ページを例とする。

<details><summary>筆者つぶやき</summary>
以下のように書いたところで問題はない。
自分で名前をつけて良いところか、modelを元に命名しないといけないところかを意識したい。
もっというと、@ebifry=Book.allでも一応成り立つ。
<div>

```erb:xxx.html.erb

    <% @books.each do |ebifry| %>
       <tr>
         <td>ebifry.title</td>
         <td>ebifry.opinion</td>
       </tr>
    <% end %>
```
</div>

</details>



```erb:xxx.html.erb
<table class='table table-hover table-inverse'>
 
  <thead>
     <tr>
       <th>本のタイトル</th>
       <th>本の感想</th>
     </tr>
  </thead>

  <tbody>
     <%  @books.each do |book|  %>
       <tr>
         <td>book.title</td>
         <td>book.opinion</td>
       </tr>
     <% end %>
  </tbody>

</table>
```
本ごとに編集ボタンや削除ボタンを付けたいなら

```erb:xxx.html.erb
<td>book.opinion</td>の下にでも、以下を挿入する。
-----------------------------------------
<td>
<%= link_to 'Destroy', book_path(book), method: :delete, data: { confirm: '本当に消しますか？' }, class: "btn btn-sm btn-danger destroy_book_#{book.id}"%>
</td>
```

##devise
今回は、deviseでログインした時に、session情報に会社名を保存したい。
以下のように、deviseコントローラに機能を追加する。
destroyはしなくていい。
なぜならdeviseで勝手にsessionは全削除してくれる。

```rb:devise/session.rb

  # POST /resource/sign_in
  # def create
  #  super
  # end

  #　↓　コメントアウトを解除して、付け加えるだけ

def create
    super
    session[:company]=current_user
  end
```
##routes

```rb:route

```