Ruby on Railsチュートリアル学習メモ

## 概要
- ドットインストール：Ruby on Rails4入門
- 基礎文法の学習
- Ruby Webアプリケーションフレームワーク
- 公式サイト
  http://rubyonrails.org/
- キーワード
	- Ruby
	- HTML/CSS/JavaScript/JQuery
	- SQLite/ActiveRecord


## DRY/CoC/MVC
- DRY
 <br>Don't Repeat Yourself
- Coc
 <br>Convention over Configuration
- MVC
 <br>Model, View, Controller


## test rails app

```bash:terminal
$rails new myapp

.....

$tree
.
├── Gemfile
├── Gemfile.lock
├── README.rdoc
├── Rakefile
├── app
│   ├── assets
│   │   ├── images
│   │   ├── javascripts
│   │   │   └── application.js
│   │   └── stylesheets
│   │       └── application.css
│   ├── controllers
│   │   ├── application_controller.rb
│   │   └── concerns
│   ├── helpers
│   │   └── application_helper.rb
│   ├── mailers
│   ├── models
│   │   └── concerns
│   └── views
│       └── layouts
│           └── application.html.erb
├── bin
│   ├── bundle
│   ├── rails
│   ├── rake
│   ├── setup
│   └── spring
├── config
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── environments
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── initializers
│   │   ├── assets.rb
│   │   ├── backtrace_silencers.rb
│   │   ├── cookies_serializer.rb
│   │   ├── filter_parameter_logging.rb
│   │   ├── inflections.rb
│   │   ├── mime_types.rb
│   │   ├── session_store.rb
│   │   └── wrap_parameters.rb
│   ├── locales
│   │   └── en.yml
│   ├── routes.rb
│   └── secrets.yml
├── config.ru
├── db
│   └── seeds.rb
├── lib
│   ├── assets
│   └── tasks
├── log
├── public
│   ├── 404.html
│   ├── 422.html
│   ├── 500.html
│   ├── favicon.ico
│   └── robots.txt
├── test
│   ├── controllers
│   ├── fixtures
│   ├── helpers
│   ├── integration
│   ├── mailers
│   ├── models
│   └── test_helper.rb
├── tmp
│   └── cache
│       └── assets
└── vendor
    └── assets
        ├── javascripts
        └── stylesheets

38 directories, 40 files

```

##Scaffold
```bash:terminal
$rails generate scaffold User name:string score:integer

Running via Spring preloader in process 32874
      invoke  active_record
      create    db/migrate/20160417055926_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.coffee
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss
```

```bash:terminal      
$rake db:migrate

== 20160417055926 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0014s
== 20160417055926 CreateUsers: migrated (0.0014s) =============================
```


## org rails app

### generate model
```bash:terminal
$rails new taskapp
```
```bash:terminal
$rails generate model Project title:string

Running via Spring preloader in process 34285
      invoke  active_record
      create    db/migrate/20160417061446_create_projects.rb
      create    app/models/project.rb
      invoke    test_unit
      create      test/models/project_test.rb
      create      test/fixtures/projects.yml
```
```bash:terminal
$rake db:migrate

== 20160417061446 CreateProjects: migrating ===================================
-- create_table(:projects)
   -> 0.0021s
== 20160417061446 CreateProjects: migrated (0.0023s) ==========================
```

###rails console

```bash:terminal
$rails console

Running via Spring preloader in process 34938
Loading development environment (Rails 4.2.5.1)
irb(main):001:0> p = Project.new(title: "p1")
=> #<Project id: nil, title: "p1", created_at: nil, updated_at: nil>

irb(main):002:0> p.save
   (0.2ms)  begin transaction
  SQL (0.9ms)  INSERT INTO "projects" ("title", "created_at", "updated_at") VALUES (?, ?, ?)  [["title", "p1"], ["created_at", "2016-04-17 06:23:24.877303"], ["updated_at", "2016-04-17 06:23:24.877303"]]
   (0.8ms)  commit transaction
=> true

irb(main):003:0> p
=> #<Project id: 1, title: "p1", created_at: "2016-04-17 06:23:24", updated_at: "2016-04-17 06:23:24">

irb(main):004:0> Project.create(title: "p2")
   (0.1ms)  begin transaction
  SQL (1.1ms)  INSERT INTO "projects" ("title", "created_at", "updated_at") VALUES (?, ?, ?)  [["title", "p2"], ["created_at", "2016-04-17 06:24:41.297234"], ["updated_at", "2016-04-17 06:24:41.297234"]]
   (0.7ms)  commit transaction
=> #<Project id: 2, title: "p2", created_at: "2016-04-17 06:24:41", updated_at: "2016-04-17 06:24:41">

irb(main):005:0> Project.all
  Project Load (0.2ms)  SELECT "projects".* FROM "projects"
=> #<ActiveRecord::Relation [#<Project id: 1, title: "p1", created_at: "2016-04-17 06:23:24", updated_at: "2016-04-17 06:23:24">, #<Project id: 2, title: "p2", created_at: "2016-04-17 06:24:41", updated_at: "2016-04-17 06:24:41">]>

irb(main):006:0> quit
```

###rails db
```bash:terminal
$rails db

SQLite version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for usage hints.

sqlite> .schema
CREATE TABLE "schema_migrations" ("version" varchar NOT NULL);
CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
CREATE TABLE "projects" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);

sqlite> select * from projects;
1|p1|2016-04-17 06:23:24.877303|2016-04-17 06:23:24.877303
2|p2|2016-04-17 06:24:41.297234|2016-04-17 06:24:41.297234

sqlite> .exit
```
### generate controller
```bash:terminal
$rails g controller Projects
Running via Spring preloader in process 35674
      create  app/controllers/projects_controller.rb
      invoke  erb
      create    app/views/projects
      invoke  test_unit
      create    test/controllers/projects_controller_test.rb
      invoke  helper
      create    app/helpers/projects_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/projects.coffee
      invoke    scss
      create      app/assets/stylesheets/projects.scss
```

### add routes

```ruby:taskapp/config/routes.rb

 Rails.application.routes.draw do
+  resources :projects
+  root 'projects#index'
+  
   # The priority is based upon order of creation: first created -> highest priority.
   # See how all your routes lay out with "rake routes".
```

```bash:terminal
$rake routes

      Prefix Verb   URI Pattern                  Controller#Action
    projects GET    /projects(.:format)          projects#index
             POST   /projects(.:format)          projects#create
 new_project GET    /projects/new(.:format)      projects#new
edit_project GET    /projects/:id/edit(.:format) projects#edit
     project GET    /projects/:id(.:format)      projects#show
             PATCH  /projects/:id(.:format)      projects#update
             PUT    /projects/:id(.:format)      projects#update
             DELETE /projects/:id(.:format)      projects#destroy
        root GET    /                            projects#index

```


### mod common template
```erb:taskapp/app/views/layouts/application.html.erb

 </head>
 <body>
 
+<%= image_tag "logo.png" %>
+
 <%= yield %>
 
+<%= link_to "Home", projects_path %>
+
 </body>
 </html>
```

### add action (index, show, new, create, edit, update, destroy, before_action)

- controller

```ruby:taskapp/app/controllers/projects_controller.rb

+ class ProjectsController < ApplicationController
+    before_action :set_project, only: [:show, :edit, :update, :destroy];
+    
+    def index
+        @projects = Project.all;
+    end
+
+    def show
+        #@project = Project.find(params[:id]);
+    end
+
+    def new
+        @project = Project.new();
+    end
+
+    def create
+        @project = Project.new(project_params);
+        if @project.save();
+            redirect_to(projects_path);
+        else
+            render 'new';
+        end
+    end
+
+    def edit
+    end
+
+    def update
+        if @project.update(project_params)
+            redirect_to(projects_path);
+        else
+            render 'edit';
+        end
+    end
+
+    def destroy
+        @project.destroy;
+        redirect_to(projects_path);
+    end
+
+    private
+        def project_params
+            # params[:project].permit(:title);
+            params.require(:project).permit(:title);
+        end
+
+        def set_project
+            @project = Project.find(params.require(:id));
+        end
+ end
```
- view - partial template

```erb:taskapp/app/views/projects/_form.html.erb
+<%= form_for @project do |f| %>
+<p>
+    <%= f.label :title %><br>
+    <%= f.text_field :title %>
+    <% if @project.errors.any? %>
+        <!-- <%= @project.errors.inspect %> -->
+        <%= @project.errors.messages[:title][0] %>
+    <% end %>
+</p>
+
+<p>
+    <%= f.submit %>
+</p>
+
+<% end %>
```

- view - template

```erb:taskapp/app/views/projects/index.html.erb
+ <ul>
+     <% @projects.each do | project | %>
+     <li>
+        <%= link_to project.title, project_path(project.id) %>
+        <%= link_to "[Edit]", edit_project_path(project.id) %>
+        <%= link_to "[Delete]", project_path(project.id), method: :delete, data: { confirm: "are you sure?" } %>
+     </li>
+     <% end %>
+</ul>
+
+<p>
+<%= link_to "add new", new_project_path %>
+</p>
```

```erb:taskapp/app/views/projects/edit.html.erb
+<h1>Edit</h1>
+
+<%= render 'form' %>
```

```erb:taskapp/app/views/projects/new.html.erb
+<h1>Add New</h1>
+
+<%= render 'form' %>
```

```erb:taskapp/app/views/projects/show.html.erb
+<h1><%= @project.title %></h1>
```


### generate model references
```bash:terminal
$rails g model Task title done:boolean project:references

Running via Spring preloader in process 68437
      invoke  active_record
      create    db/migrate/20160418062553_create_tasks.rb
      create    app/models/task.rb
      invoke    test_unit
      create      test/models/task_test.rb
      create      test/fixtures/tasks.yml
```
```bash:terminal
$rails g controller Tasks
Running via Spring preloader in process 68768
      create  app/controllers/tasks_controller.rb
      invoke  erb
      create    app/views/tasks
      invoke  test_unit
      create    test/controllers/tasks_controller_test.rb
      invoke  helper
      create    app/helpers/tasks_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/tasks.coffee
      invoke    scss
      create      app/assets/stylesheets/tasks.scss
```


### add action (index, show, new, create, edit, update, destroy, before_action)

- controller

```ruby:taskapp/app/controllers/tasks_controller.rb
+class TasksController < ApplicationController
+    def create
+        @project = Project.find(params.require(:project_id));
+        @task = @project.tasks.create(task_params);
+        redirect_to project_path(@project.id);
+    end
+
+    def destroy
+        @task = Task.find(params.require(:id));
+        @task.destroy;
+        redirect_to project_path(params.require(:project_id));
+    end
+
+    def toggle
+        render nothing: true;
+        
+        @task = Task.find(params[:id]);
+        @task.done = !@task.done;
+        @task.save;
+    end
+
+    private
+        def task_params
+            params.require(:task).permit(:title);
+        end
+end
```

```ruby:taskapp/config/routes.rb
 Rails.application.routes.draw do
-  resources :projects
+  resources :projects do
+    resources :tasks, only: [:create, :destroy]
+  end
+
   root 'projects#index'
-  
+  post '/projects/:project_id/tasks/:id/toggle' => 'tasks#toggle'
+
   # The priority is based upon order of creation: first created -> highest priority.
   # See how all your routes lay out with "rake routes".
 
 
```

- model

```ruby:taskapp/app/models/project.rb
 class Project < ActiveRecord::Base
+    has_many :tasks;
     # validates :title, presence: true;
     validates :title,
         presence: { message: "入力してください" },
```

```ruby:taskapp/app/models/task.rb
+class Task < ActiveRecord::Base
+  belongs_to :project;
+  validates :title, presence: true;
+  scope :unfinished, -> { where(done: false) }
+end
```

- view

```erb:taskapp/app/views/projects/index.html.erb

  <ul>
     <% @projects.each do | project | %>
     <li>
-        <%= link_to project.title, project_path(project.id) %>
+        <%= link_to project.title, project_path(project.id) %>(<%= project.tasks.unfinished.count %>/<%= project.tasks.count %>)
         <%= link_to "[Edit]", edit_project_path(project.id) %>
         <%= link_to "[Delete]", project_path(project.id), method: :delete, data: { confirm: "are you sure?" } %>
     </li>
```

```erb:taskapp/app/views/projects/show.html.erb

+<ul>
+    <% @project.tasks.each do |task| %>
+    <li>
+        <%= check_box_tag '', '', task.done, {'data-id' => task.id, 'data-project_id' => task.proje
ct_id } %>
+        <%= task.title %>
+        <%= link_to "[Delete]", project_task_path(task.project_id, task.id), method: :delete, data:
 { confirm: "are you sure?" } %>
+    </li>
+    <% end %>
+
+    <li>
+        <%= form_for [@project, @project.tasks.build] do |f| %>
+            <%= f.text_field :title %>
+            <%= f.submit %>
+        <% end %>
+    </li>
+</ul>
+<script>
+    $(function(){
+        $("input[type=checkbox]").click(function() {
+            $.post('/projects/'+$(this).data('project_id')+'/tasks/'+$(this).data('id')+'/toggle');
+        });
+    });
+</script>
```