第1回 Rails勉強会


# 目的
@  タスク管理機能を作る
 - ルーティングの使用 
 - フォームの使用
 - SASSの使用
 - CouchDBの使用(第２回にて予定)

# 事前準備
## Railsのインストール
[こちら](http://qiita.com/CyberMergina/items/3970f7aebf50087d88af)の記事の最下部に記載しています。
*※ 仮想環境でRails環境を整えるまでのまとめです。*

# Railsプロジェクトの作成
シェルにて「rails new [プロジェクト名]」で一発でできます。

`rails new sampleProject`

# Railsサーバーで起動

`rails server`
IP指定が必要なら `rails server -b [IPアドレス]`

# コントローラの追加

+ シェルで**railsジェネレータ**を使用した追加方法
**rails g controller [コントローラ名] [ページ] [ページ]**
`rails g controller tasks index detail`

+ 作成された主要ファイル
**app/controllers/tasks_controller.rb**
　コントローラ。主にデータの受け渡しやデータの加工を行う
**app/helpers/tasks_helper.rb**
　ヘルパー。主にViewの拡張として使用する。
**app/views/tasks**
　ビュー。機能ごとにディレクトリが分かれており、`erb`という拡張子のファイルが作成される。
　記述はHTMLと変わらないが、railsコードとの連携が取れるようなタグが用意されている。
**assets/javascripts/tasks.coffee**
　ページ単位のCoffeeScript
**assets/stylesheets/tasks.scss**
　ページ単位のSCSSファイル


# http：//X.X.X:3000/ でメインのページへリダイレクト

+ `root :to => '[コントローラ名]#[メソッド名]'`の形で`config/routes.rb`に追記

```rb:config/routes.rb
Rails.application.routes.draw do
  # 追加
  root :to => 'tasks#index'
  get 'tasks/index'
```

## ルーティングの補足

+ ルーティングとは
ルーティングとはURLに対し、HTTPメソッドの種類(GET/POST/PATCH/PUT/DELETE)やパラメータを指定し、 
安全なアクセスの為にアクセス制限をするもの。
と、個人的に解釈しています。

＋ HTTPメソッドの種類
アクセス後の作業によってメソッドを選択する必要があります。

| HTTPメソッド | 概要 |
| ---- | ---- |
| GET | ページの表示 |
| POST | データ受け渡し(submit) |
| PATCH | データ更新 |
| PUT | データ削除からの再構築 |
| DELETE | データ削除 |
PUTとPATCHについては「[HTTPメソッドのPUTメソッドとPATCHメソッドの違い](http://blog.kotamiyake.me/2013/12/09/defference-between-put-and-patch/)」を参考にしました。

+ 書き方
config/routes.rb にサンプルが記述されているので参考にするといいかと思います。
または[Rubyドキュメント](http://railsdoc.com/routes)確認する。

+ 定義したルーティングの確認方法
シェル： `rake routes`
ブラウザ： `http:localhost:3000/rails/info/routes`

+ 便利な使い方
　定義したものに対して、別名が付けられます。
　引数を使用していないものに関しては別名は自動で付けられます。(恐らく)
 　上記の「確認方法」で見てみると「tasks_index_path」という表記があるはずです。
  　わざわざ「controller, action, method」を指定しなくても別名を使用すると綺麗に書けます。

# ベースとなるコードの準備

## HTML(views/tasks/index.html.erb)

今のところいつものhtmlのコードと変わらないです。

```erb:views/tasks/index.html.erb
<div id="taskIndexArea">
	<form>
		<div id="taskAddArea">
			<div id='taskInputArea'><input type="text" /></div>
			<div id='taskAddBtnArea'><button>ADD</button></div>
		</div>
	</form>
	<div id="taskListArea">
		<ul>
			<li>dummydummydummydummy [ <a href="#">remove</a> ]</li>
		</ul>
	</div>
</div>
```

## SASS(assets/stylesheets/applications.scss, assets/stylesheets/tasks.scss)

+ プロジェクト全体にかけるスタイルは **applications.css** へ

```css:assets/stylesheets/applications.css
input[type='text'] {
	padding: 5px;
	border: 1px solid #999;
	border-radius: 5px;
}
```

+ 機能単位にかけるスタイルは **[機能名].scss** へ

```scss:assets/stylesheets/tasks.scss
$incontent-width: 80%;
@mixin flexRowBox {
    display: inline-flex;
    flex-direction: row;
}

#taskIndexArea {
    width: $incontent-width;
    margin: 0 auto;

    #taskAddArea {
        display: flex;

        #taskInputArea {
            @include flexRowBox;

            width: 90%;

            input {
                width: 100%;
            }
        }

        #taskAddBtnArea {
            @include flexRowBox;

            width: 10%;
        }
    }

    #taskListArea {
        ul {
            padding: 0;
        }

        li {
            word-break: break-word;
            list-style: none;
        }
    }
}

```

# ControllerからViewにデータを渡そう

## Controllerにてデータセット

```rb:app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  # グローバル変数にデータをセットする
  $taskList = [
    'dummydummydummydummy1',
    'dummydummydummydummy2',
    'dummydummydummydummy3'
  ]

  def index
  end

end

```

## Viewでデータを受け取り、ループをして表示

*#taskListArea*を書き換え。

```erb:app/views/tasks/index.erb
    <div id="taskListArea">
		<ul>
			<% $taskList.each_with_index do | value, key | %>
				<li><%= value %> [ <a href="#">remove</a> ]</li>
			<% end %>
		</ul>
	</div>
```

+ *<% %>*と*<%= %>*
-　*<%  %>*：ビューに出力しないもの
-　*<%= %>*：ビューに結果を出力する
　　他にも種類があり、使い分けが必要です。
  ※ 本家リンク：[ERBとは](http://railsdoc.com/view#ERB%E3%81%A8%E3%81%AF)

+ .each_with_index
　配列の添え字付きループに使用する。
　例では、データを持っている配列 '$taskList' を .each_with_index関数を使ってループさせており
　*value*という変数には値、*key*という変数には添え字が毎度セットされます。

# ビューからフォームのデータを渡そう(SUBMIT)

## ルーティングの定義追記

```rb:config/routes.rb
  post 'tasks/index', to: "tasks#add"
```

## ViewからControllerへデータを渡せるようにしましょう

*#taskIndexArea*の下のformタグの中を書き換えます

```erb:app/views/tasks/index.html.erb
<%= form_tag('/tasks/index') do %>
	<div id="taskAddArea">
		<div id='taskInputArea'><%= text_field_tag(:text) %></div>
		<div id='taskAddBtnArea'><%= button_to "ADD", :action => "add" %></div>
	</div>
<% end %>
```

+ form_tag('url') do ~ end
formタグを作成します。

+ text_field_tag(:名前)
テキストボックスを作成します。
*:名前*の部分はname属性になります。

+ button_to
buttonタグを作成します。
多くのオプションが存在します。
例では *button_to [表示する文字列], [遷移先]*  をセットしてます。

## 配列にViewから渡された文字列を追加するメソッドを作成

```rb:app/controllers/tasks_controller.rb

  def index
  end

# 追記
  def add
  # $taskListの末尾パラメーターにセットされている text　という名前のデータをセットする
  	$taskList << params[:text]
    render :index
  end
```

+ render
表示するビューを指定している。
例では、メソッド名のと同名のビューが存在しないので *index.html.erb* を指定している。


+ 補足
params の中身が見たい場合は、通過するメソッドの中で `puts params`としてみましょう。
`rails s`をしているシェルに中身が表示されます。


# 削除機能の追加

## ルーティングの定義追記

```rb:config/routes.rb
  delete 'tasks/:id', to: "tasks#remove", as: "tasks_delete"
```

削除の機能なので `delete` を使用します。
また、パスの中に`:名前` とすることで、その位置に入ってくる文字列がcontroller内部でparamsから受け取れるようになります。
これはdeleteだけでなく、puts,patchなどでも使用できます。

```rb:-----.rb
# 例：http://0.0.0.0:3000/tasts/1234 でアクセス（htmlメソッド:delete）

def remove
  puts params[:id] # 1234 が文字列として取得できる
end
```

## ViewからControllerに削除する添え字を渡す

liタグの中に削除用のリンクを設置

```erb:app/views/tasks/index.html.erb
	<div id="taskListArea">
		<ul>
			<% $taskList.each_with_index do | value, key | %>
			<li><%= value %> [ <%= link_to "Remove", tasks_delete_path(key), :method => "delete" %> ] </li>
			<% end %>
		</ul>
	</div>
```

+ link_to
　aタグのリンクを作成します。
　例では、*link_to [表示する文字列], [遷移先], :method => [アクションの種類]*をセットしています。

## Controller でパラメータの添え字を受け取り、配列から対象を削除するメソッドを作成

```rb:app/controllers/task_controller.rb
  # 追加
  def remove
    $taskList.delete_at(params[:id].to_i)
    render :index
  end
```

+ .delete_at()
配列から、引数に渡された添え字のデータを削除する関数。

+ .to_i
文字列を数値に変換する関数。

第２回は[こちら](http://qiita.com/CyberMergina/items/a7bd1c18c765a7fdbf67)！