Laravel で Ruby on Rails チュートリアル【5章】アセット

## 環境
- Laravel 8.6
- PHP 8.0
- Bootstrap 5.1

## 5.1 構造を追加する

### 5.1.1 ナビゲーション

ルーティングの修正

```php:/routes/web.php
Route::get('/', [StaticPagesController::class, 'home'])->name('home');
```

共通ビューを修正

```html:/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>{{ full_title($__env->yieldContent('title')) }}</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
    <link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
</head>

<body>
<header class="navbar fixed-top navbar-dark p-0">
    <div class="container">
        {{ link_to_route('home', "sample app", ["id" => "logo"]) }}
        <nav>
            <ul class="nav navbar-nav">
                <li>{{ link_to_route("home", "Home") }}</li>
                <li>{{ link_to_route("home", "Help") }}</li>
                <li>{{ link_to_route("home", "Log in") }}</li>
            </ul>
        </nav>
    </div>
</header>
<div class="container">
    @yield('content')
</div>
</body>
</html>
```

homeのビューを修正

```html:/resources/views/static_pages/home.blade.php
@extends('layouts.application')

@section('content')
    <div class="center bg-light p-5 my-4 rounded">
        <h1>Welcome to the Sample App</h1>

        <h2>
            This is the home page for the
            <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
            sample application.
        </h2>

        {{ link_to_route("home", "Sign up now!", [], ["class" => "btn btn-lg btn-primary", "role" => "button"]) }}
    </div>

    <a href="http://rubyonrails.org/"><img src="{{ asset('/img/rails.png') }}" alt="Rails logo"></a>
@endsection
```

### 5.1.2 BootstrapとカスタムCSS

nodemoduleをインストール

```bash
sail npm install
```

CSSとJSをコンパイル
以降CSSとJSを修正した場合に実行

```bash
sail npm run prod
```

### 5.1.3 パーシャル(partial)

ビューを修正

```html:/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>{{ full_title($__env->yieldContent('title')) }}</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
    <link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
</head>

<body>
@include('layouts.header')
<div class="container">
    @yield('content')
</div>
@include('layouts.footer')
</body>
</html>
```
```html:/resources/views/layouts/header.blade.php
<header>
    <nav class="navbar navbar-expand fixed-top navbar-dark bg-dark">
        <div class="container">
            {{ link_to_route('home', "sample app", [], ["id" => "logo", "class" => "navbar-brand"]) }}
            <ul class="navbar-nav">
                <li class="nav-item">{{ link_to_route("home", "Home", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item">{{ link_to_route("home", "Help", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item">{{ link_to_route("home", "Log in", [], ["class" => "nav-link"]) }}</li>
            </ul>
        </div>
    </nav>
</header>
```
```html:/resources/views/layouts/footer.blade.php
<footer class="footer">
    <nav class="navbar navbar-expand-lg">
        <div class="container">
            <small>
                The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
                by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
            </small>
            <ul class="navbar-nav">
                <li class="nav-item">{{ link_to_route("home", "About", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item">{{ link_to_route("home", "Contact", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item"><a href="http://news.railstutorial.org/" class="nav-link">News</a></li>
            </ul>
        </div>
    </nav>
</footer>
```
```sass:/resources/sass/app.scss
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');

// Variables
// @import 'variables';

// Bootstrap
@import '~bootstrap/scss/bootstrap';

/* universal */

body {
    padding-top: 60px;
}

section {
    overflow: auto;
}

textarea {
    resize: vertical;
}

.center {
    text-align: center;
}

.center h1 {
    margin-bottom: 10px;
}

/* typography */

h1, h2, h3, h4, h5, h6 {
    line-height: 1;
}

h1 {
    font-size: 3em;
    letter-spacing: -2px;
    margin-bottom: 30px;
    text-align: center;
}

h2 {
    font-size: 1.2em;
    letter-spacing: -1px;
    margin-bottom: 30px;
    text-align: center;
    font-weight: normal;
    color: #777;
}

p {
    font-size: 1.1em;
    line-height: 1.7em;
}

/* header */

#logo {
    float: left;
    margin-right: 10px;
    font-size: 1.7em;
    color: #fff;
    text-transform: uppercase;
    letter-spacing: -1px;
    padding-top: 9px;
    font-weight: bold;
}

#logo:hover {
    color: #fff;
    text-decoration: none;
}

/* footer */

footer {
    margin-top: 45px;
    padding-top: 5px;
    border-top: 1px solid #eaeaea;
    color: #777;
}

footer .nav-link {
    color: #555;
}

footer .nav-link:hover {
    color: #222;
}

footer small {
    float: left;
}

footer ul {
    float: right;
    list-style: none;
}

footer ul li {
    float: left;
    margin-left: 15px;
}
```

#### 演習

```php:/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>{{ full_title($__env->yieldContent('title')) }}</title>
    @include('layouts.rails_default')
</head>

<body>
@include('layouts.header')
<div class="container">
    @yield('content')
</div>
@include('layouts.footer')
</body>
</html>
```
```html:/resources/views/layouts/rails_default.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
<script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
<link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
```

## 5.2 Sassとアセットパイプライン

### 5.2.1 アセットパイプライン

### 5.2.2 素晴らしい構文を備えたスタイルシート

# 5.3 レイアウトのリンク

### 5.3.1 Contactページ

### 5.3.2 RailsのルートURL

ルーティングの修正

```php:/routes/web.php
Route::get('/', [StaticPagesController::class, 'home'])->name('home');
Route::get('about', [StaticPagesController::class, 'about'])->name('about');
Route::get('help', [StaticPagesController::class, 'help'])->name('help');
Route::get('contact', [StaticPagesController::class, 'contact'])->name('contact');
```

テスト修正

```php:/tests/Unit/StaticPagesControllerTest.php
    public function testGetRoot()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
        $dom = $this->dom($response->content());
        $this->assertSame($this->base_title, $dom->filter("title")->text());
    }

    public function testGetAbout()
    {
        $response = $this->get(route('about'));
        $response->assertStatus(200);
        $dom = $this->dom($response->content());
        $this->assertSame("About | {$this->base_title}", $dom->filter("title")->text());
    }

    public function testGetHelp()
    {
        $response = $this->get(route('help'));
        $response->assertStatus(200);
        $dom = $this->dom($response->content());
        $this->assertSame("Help | {$this->base_title}", $dom->filter("title")->text());
    }

    public function testGetContact()
    {
        $response = $this->get(route('contact'));
        $response->assertStatus(200);
        $dom = $this->dom($response->content());
        $this->assertSame("Contact | {$this->base_title}", $dom->filter("title")->text());
    }
```

### 5.3.3 名前付きルート

headerのリンクを修正

```html:/resources/views/layouts/header.blade.php
<header>
    <nav class="navbar navbar-expand fixed-top navbar-dark bg-dark p-0">
        <div class="container">
            {{ link_to_route('home', "sample app", [], ["id" => "logo", "class" => "navbar-brand"]) }}
            <ul class="navbar-nav">
                <li class="nav-item">{{ link_to_route("home", "Home", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item">{{ link_to_route("help", "Help", [], ["class" => "nav-link"]) }}</li>
                <li class="nav-item">{{ link_to_route("home", "Log in", [], ["class" => "nav-link"]) }}</li>
            </ul>
        </div>
    </nav>
</header>
```

footerのリンクを修正

```html:/resources/views/layouts/footer.blade.php
<footer class="footer">
    <small>
        The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
        by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
    </small>
    <nav>
        <ul>
            <li>{{ Html::linkRoute("about", "About") }}</li>
            <li>{{ Html::linkRoute("contact", "Contact") }}</li>
            <li><a href="http://news.railstutorial.org/">News</a></li>
        </ul>
    </nav>
</footer>
```

### 5.3.4 リンクのテスト

テストの作成

```bash
sail artisan make:test SiteLayoutTest
```

テストの中身

```php:/tests/Feature/SiteLayoutTest.php
class SiteLayoutTest extends TestCase
{
    public function testLayoutLinks()
    {
        $response = $this->get('/');
        $response->assertViewIs("static_pages.home");
        $dom = $this->dom($response->content());
        $this->assertSame(url("/"), $dom->filter('a:contains("sample app")')->attr("href"));
        $this->assertSame(url("/"), $dom->filter('a:contains("Home")')->attr("href"));
        $this->assertSame(route("help"), $dom->filter('a:contains("Help")')->attr("href"));
        $this->assertSame(route("about"), $dom->filter('a:contains("About")')->attr("href"));
        $this->assertSame(route("contact"), $dom->filter('a:contains("Contact")')->attr("href"));
    }
}
```

#### 演習

テスト追加

```php:/tests/Feature/SiteLayoutTest.php
class SiteLayoutTest extends TestCase
{
    public function testLayoutLinks()
    {
        $response = $this->get("/");
        $response->assertViewIs("static_pages.home");
        $dom = $this->dom($response->content());
        $this->assertSame(url("/"), $dom->filter('a:contains("sample app")')->attr("href"));
        $this->assertSame(url("/"), $dom->filter('a:contains("Home")')->attr("href"));
        $this->assertSame(route("help"), $dom->filter('a:contains("Help")')->attr("href"));
        $this->assertSame(route("about"), $dom->filter('a:contains("About")')->attr("href"));
        $this->assertSame(route("contact"), $dom->filter('a:contains("Contact")')->attr("href"));
        $response = $this->get("contact");
        $response->assertViewIs("static_pages.contact");
    }
}
```

## 5.4 ユーザー登録

### 5.4.1 Usersコントロール

Usersコントローラーを作成

```bash
sail artisan make:controller UsersController --resource
```
```php:/app/Http/Controllers/UsersController.php
class UsersController extends Controller
{
    public function create()
    {
        return view('users.create');
    }
}
```

### 5.4.2 ユーザー登録用URL

ユーザー登録ページ作成

```php:/routes/web.php
Route::get('signup', [UsersController::class, 'create'])->name('signup');
```
```html:/resources/views/users/create.blade.php
@extends('layouts.application')

@section('title', 'Sign up')

@section('content')
<h1>Sign up</h1>
<p>This will be a signup page for new users.</p>
@endsection
```
```php:/tests/Unit/UsersControllerTest.php
class UsersControllerTest extends TestCase
{
   
    public function testGetCreate()
    {
        $responce = $this->get(route('signup'));
        $responce->assertStatus(200);
    }
}
```

# 5.5 最後に

# 参考
https://getbootstrap.jp/docs/5.0/components/navbar/
https://getbootstrap.jp/docs/5.0/components/buttons/