Railsチュートリアル備忘録 -モデル/ビュー/コントローラー（&ルーティング）編-

# rails作成
```
rails new アプリ名
```
# コントローラー
## コントローラの作成・消去
### 作成
```
rails g controller コントローラー名（複数形） アクション名
例 $ rails g controller StaticPages home help
```
### 消去
```
rails destroy controller コントローラー名（複数形） アクション名
例 $ rails generate controller StaticPages home help
```
### postの制限
```
  def create
    @user = User.new(user_params)
    .
    .
    .
  end


  private
    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
```
### 遷移
* redirect_to : getリクエスト、ルートを経由しアクションを実行。そのためアクション内のインスタンス変数は使えない 
* render : ルートを経由せず、Viewを読みだす。そのためインスタンス変数を用いることができる。

[redirect_toとrenderの違い](https://qiita.com/1ulce/items/282cccba1e44158489c8)

### 一時表示
#### redirect_to-flash
```
    flash[:success] = "Welcome to the Sample App!"
    redirect_to @user
(redirect_to @userは/User/:idにリダイレクト)
```

HTML

```
      <% flash.each do |message_type, message| %>
        <div class="alert alert-<%= message_type %>"><%= message %></div>
      <% end %>
message_type => success
message => Welcome to the Sample App!
```
#### render-flash.new
# モデル
## モデルの作成/消去
### 作成（マイグレーションの作成）
```
$ rails g model モデル名（単数形） カラム名:データ型
例：rails generate model User name:string email:string
```
db/migrateに生成される
### 消去
```
$ rails destroy model モデル名
```
### 
## データベース
## マイグレーションの追加
```
rails generate migration マイグレーション名 追加事項
例　rails generate migration add_password_digest_to_users password_digest:string
```
### マイグレーションの適用
```
$ rails db:migrate
```
### 消去
```
rails db:migrate:reset
```
### マイグレーションの取り消し
```
$ rails db:rollbac
```
### マイグレーションのバージョン指定で適用
```
$ rails db:migrate VERSION=0
```
### パスワード
#### gemのインストール
```
gem 'bcrypt',         '3.1.12'
```
```
bundle install
```
#### パスワードの生成
```app/models/user.rb
has_secure_password
```
#### パスワードの検証
````
user=User.find_by(***)
user && user.authenticate(params[:session][:password])
=> true 整合
=> false 不整合
````
|User	|Password	|a && b|
|  ----     |  ----             |  ----    |
|存在しない	|何でもよい	|(nil && [オブジェクト]) == false|
|有効なユーザー|	誤ったパスワード	|(true && false) == false|
|有効なユーザー	|正しいパスワード|	(true && true) == true|


## オブジェクト
### 生成(new)
```
user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "mhartl@example.com",created_at: nil, updated_at: nil>
```
### 保存(save)
```
user.save
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.8ms)  INSERT INTO "users" ("name", "email", "created_at",
  "updated_at") VALUES (?, ?, ?, ?)  [["name", "Michael Hartl"],
  ["email", "mhartl@example.com"], ["created_at", 2016-05-23 19:05:58 UTC],
  ["updated_at", 2016-05-23 19:05:58 UTC]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
```
### 生成/保存の同時実行(create)
```
>> foo = User.create(name: "Foo", email: "foo@bar.com")
#<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2016-05-23 19:19:06", updated_at: "2016-05-23 19:19:06">
```
### 消去(destroy)
```
foo.destroy
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.2ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 3]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2016-05-23 19:19:06", updated_at: "2016-05-23 19:19:06">
```
### 検索
#### idでの検索(find)
```
User.find(id番号)
例 User.find(3)
```
#### 特定の属性での検索(find_by)
```
User.find_by(email:"mhartl@example.com")
User.find_by(id:1)
```
#### すべてを返す(all)
````
User.all
````
### エラー
#### 内容(errors.full_messages)
````
>> user.errors.full_messages
=> ["Name can't be blank"]
````
#### 存在(errors.any?)
```
>> user.errors.empty?
=> false
```
#### エラーの個数(errors.count)
```
>> user.errors.count
=> 2
```
### 更新
#### 更新
```
>> user           # userオブジェクトが持つ情報のおさらい
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com",
created_at: "2016-05-23 19:05:58", updated_at: "2016-05-23 19:05:58">
>> user.email = "mhartl@example.net"
=> "mhartl@example.net"
>> user.save
=> true
```
#### 更新/保存の同時実行(update_attributes)
```
>> user           # userオブジェクトが持つ情報のおさらい
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com",
created_at: "2016-05-23 19:05:58", updated_at: "2016-05-23 19:05:58">
>> user.update_attributes(name: "The Dude", email: "dude@abides.org")
=> true
>> user.name
=> "The Dude"
>> user.email
=> "dude@abides.org"
```
## 制約の設定
### 存在性
例 nameが空ではない

```app/models/user.rb
validates :name, presence: true
```
### 長さ
```app/models/user.rb
validates :name,  length: { maximum: 50 }
```
### フォーマット（メールアドレスなど）
```
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, format:     { with: VALID_EMAIL_REGEX }
```
### 保存時
#### 小文字指定
```
before_save { self.email = email.downcase }
```
### 一意性
大文字小文字を区別する

```
validates :email, uniqueness: true
```
大文字小文字を区別しない

```
validates :email,uniqueness: { case_sensitive: false }
```
### データベースレベルでの一意性
特定のカラムにインデックスを付与し、その数値がデータベースレベルで一意であることを確認する
#### マイグレーション作成
```
rails generate migration マイグレーション名
```
#### マイグレーションファイルの編集（インデックス付与）
```db/migrate/[timestamp]_マイグレーション名.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
  def change
    add_index :users, :email, unique: true
  end
end
```
#### マイグレート
```
$ rails db:migrate
```
#### サンプルデータの削除
```test/fixtures/users.yml
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/
# FixtureSet.html

one:
  name: MyString
  email: MyString

two:
  name: MyString
  email: MyString
```

以上のコードの削除が必要
# ビュー
## レイアウトの共通化
### ビューへの変数埋め込み
```
<% provide(:title, "Home") %>
```
### 共通
```app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```
# ルーティング
## root
```
root "コントローラ名#アクション名"
例 root "static_pages#home"
```
## REST
```config/routes.rb
resources :users
```
|HTTPリクエスト|URL|アクション|名前付きルート|用途|
| ---- | ---- |---- | ---- |---- | 
|GET	|/users	|index	|users_path	|すべてのユーザーを一覧するページ|
|GET	|/users/1	|show	|user_path(user)	|特定のユーザーを表示するページ|
|GET	|/users/new	|new	|new_user_path	|ユーザーを新規作成するページ (ユーザー登録)|
|POST	|/users	|create	|users_path	|ユーザーを作成するアクション|
|GET	|/users/1/edit	|edit	|edit_user_path(user)	|id=1のユーザーを編集するページ|
|PATCH	|/users/1	|update	|user_path(user)	|ユーザーを更新するアクション|
|DELETE	|/users/1	|destroy	|user_path(user)	|ユーザーを削除するアクション|

## その他
```
get "/名前" => "コントローラ名#アクション名"
post "/名前" => "コントローラ名#アクション名"
```
# gemの更新
```
$ bundle install
$ bundle update
```
[bundle installとbundle updateの違い](https://qiita.com/seiya2130/items/49af14cfb29e036546b9)
# 追加中