Rails-MessageBoard


![](http://findicons.com/files/icons/1607/ruby_on_rails/128/ror_logo.png)

## Controller
`rails generate controller messages index`
	- route.rb

## Model
`rails generate model Message name:string body:string`
	- migration file
		- データベースの作成、修正する機能
		- SQLが必要ない
		- db/schema.rbに実行済みmigrationが記録される

* `rails db:migrate`

* `resources :messages`
	- URLヘルパ  
	リソースに必要なURLを自動的に生成する仕組みのこと
	link_toで使用する  
	_pathをつけた場合は相対パス  
	_urlをつけた場合は「http://〜」

## ERB
`<%= code %>`　codeを実行して、結果を文字列として埋め込む
`<%  code %>` codeを実行するだけ、結果は埋め込まない
	* form_for(form helper)  
		* 特定のモデルオブジェクトを作成、編集するためのフォームを自動で生成  
		* モデルオブジェクトとフォームを関連付けることで、フォームで入力した値をモデルオブジェクトに割り当てたり、編集時にすでに保存されている値やエラーをモデルオブジェクトを介してフォームに表示

```
<form class="new_message" id="new_message" action="/messages" accept-charset="UTF-8" method="post">
```
* routes.rbで、`resources :messages`の記述を追加したので、form_forにMessageモデルの初期化されたオブジェクトを引数として渡した場合は、URLとしてmessages_path、HTTPメソッドとしてPOSTがformタグの属性として自動的にセットされる
* ブロック引数のfはフォームビルダ  
`f.text_field :name` type="text"のinputタグ  
`f.text_field :body` type="text"のinputタグ  
`f.submit` type="submit"のinputタグ

## Message作成の流れ
	1. フォームに値を入力し送信ボタンを押すと /messages,URLにPOSTでリクエストがパラメータと共に送信される
	2. routes.rbで設定したMessagesControllerのcreateアクションが呼ばれる
	3. createアクションでnameと、bodyが含まれたパラメータ(message_params)を受け取る
	4. Messageモデルのインスタンスを生成(Message.new)する
	5. `@message.save`でDBへ保存
	6. route URLにredirect
* フォームから送信されたparamはcontrollerではparamsで取得

```
{ :message => {
    :name => "名前の入力内容",
    :body => "内容の入力内容"
  }
}
```
* strong parameter  
意図せぬparamを送ってきた場合に、検証する。不正な操作などを防ぐ。

```
  private
  def message_params
    params.require(:message).permit(:name, :body)
  end
```
paramsに`:message`というキーが存在するか検証し、キーが`:name`と`:body`の値のみ受け取るようにフィルタリング

## Bootstrap
`app/views/layouts/application.html.erb`
`app/views/messages/index.html.erb`

```
<form role="form">
  <%= form_for(@message) do |f| %>
    <div class="form-group">
      <label for="exampleInputEmail1">Name:</label>
      <%= f.text_area :name, :class => "form-control" %>
    </div>
  
    <div class="form-group">
      <label for="exampleInputEmail1">Content:</label>
      <%= f.text_area :body, :class => "form-control" %>
    </div>
    <%= f.submit class: "btn btn-sm btn-primary" %>
  <% end %>
</form>
```

## Validation

```
  # 名前は必須入力かつ20文字以内
  validates :name , length: { maximum: 20 } , presence: true
  # 内容は必須入力かつ2文字以上30文字以下
  validates :body , length: { minimum: 2, maximum: 30 } , presence: true
```

controller→バリデーションに失敗した場合はerror表示

```
@messages = Message.all
flash.now[:alert] = "failed to save"
render 'index'
```
view→errorメッセージ表示

```
<% @message.errors.full_messages.each do |full_message| %>
	<li>
		<%= full_message %>
	</li>
<% end %> 
```

## Update,Delete

```
  resources :messages, except: [:index, :new]
  #resources :messages, only: [:create, :show, :edit, :destroy, :update]
```

### Link
`link_to Link Name, Link URL`
`<%= link_to "edit" , edit_message_path(message) %>`
`edit_message_path(message)`→`/messages/message.id/edit`

### before_action
フィルタという機能で各アクションの前後に任意の処理を実行できる

### params
ユーザーがフォームから送信したパラメータをコントローラ側で受け取るためのハッシュ

1. `<%= link_to "edit" , edit_message_path(message) `%>→`/messages/message.id/edit`
2. GETでアクセスすることで`messages#edit`へ到達
3. `params[:id]`に1が代入されてコントローラに渡される
4. `@message = Message.find(params[:id])`→`@message = Message.find(1)`

このようにURLによって要求されるリソースを特定できる設計のことをREST

## Column追加
`rails g migration add_age_to_messages age:integer`
### model
added validation
### view
added
`message.age`
`<%= f.text_field :age, :class => "form-control" %>`
### controller
added strong parameter

## Error,Debug
### NoMethodError in …
* メソッドが定義されていない
* 正しいデータが入っていない

### AcitveRecord::RecordNotFound in …
* DBにデータが存在しない
* パラメータが間違っている

### Missing Template
コントローラのアクションに対応するビュー（ERBファイル）が存在しない

### Syntax Error
文法エラー

### pry debugger
#### binding.pry
* message_params
* @message
* next
* exit