【初心者】Ruby on Railsでブログを作る

# 概要 :feet: 

Ruby on Railsの学習をしています。
1日1つRailsで練習アプリを作る生活3日目です。

明日から、アプリ開発をしようと思っているので最終チェックですね！

参考サイトのを簡略化して実装しているだけなので、詳しくしたり方はそちらをご覧ください。

# 新規アプリを作成 :feet: 

```shell
ubuntu@ubuntuv:~/デスクトップ/projectX$ rails new blog
ubuntu@ubuntuv:~/デスクトップ/projectX$ cd blog
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ bundle update
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ bundle install
```

# Hello Ruby on Rails :feet: 

`GET`した`articles`リクエストを`ArticlesController`の`index`アクションに対応付ける
つまり、`/articles`にアクセスが来たら、`hello ruby on rails`が出るように表示したい！

```config/routes.rb
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  get "/articles", to: "articles#index"

  # Defines the root path route ("/")
  # root "articles#index"
end
```

コントローラーを作成します。
あらかじめルーティングの設定をしているので、`--skip-routes`を使用してルーティング設定を省きます

```shell
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails generate controller Articles index --skip-routes
```

HTMLファイルを編集しましょう！

```html:app/views/articles/index.html.erb
<h1>hello ruby on rails</h1>
```

以下のコマンドでサーバーをスタートさせる

```shell
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails s
```

`http://127.0.0.1:3000/articles`を開くと、`hello ruby on rails`が出るはず！

# アプリケーションのHomeページを設定 :feet: 

`http://localhost:3000`を開いた際にはデフォルト画面なので、それを編集しましょう！

以下のようにルーティング設定を編集してください

```config/routes.rb
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
  root "articles#index"

  get "/articles", to: "articles#index"

  # Defines the root path route ("/")
  # root "articles#index"
end
```

これで、`root`にアクセスすると`articles#index`が呼ばれるようになりました！

# モデルを作る :feet: 

モデルはアプリケーションとデーターベースの仲立ちを担うものです。

```shell
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails generate model Article title:string body:text
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails db:migrate
```

# 記事を一覧表示できるように.... :feet: 

コントローラに記事の一覧を取得できる変数を作成する。

```app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end
end
```

`app/views/articles/index.html.erb`でその変数を呼び出して、表示する

```html:app/views/articles/index.html.erb
<h1>Articles</h1>

<ul>
  <% @articles.each do |article| %>
    <li>
      <%= article.title %>
    </li>
  <% end %>
</ul>
```

DBに新しいデータを追加する

最後に`true`と出たら、`exit`で終了。

```shell
ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails console

Loading development environment (Rails 7.0.2.3)

irb(main):001:0> article = Article.new(title: "HELLO Rails", body:"I am on Rails!")
   (0.5ms)  SELECT sqlite_version(*)
=>                                                                                                   
#<Article:0x0000561acbf58a48                                                                         
...                                                                                                  

irb(main):002:0> article.save
  TRANSACTION (0.1ms)  begin transaction
  Article Create (0.2ms)  INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "HELLO Rails"], ["body", "I am on Rails!"], ["created_at", "2022-04-22 06:10:07.418372"], ["updated_at", "2022-04-22 06:10:07.418372"]]                                         
  TRANSACTION (1.8ms)  commit transaction                                                            
=> true                                                                                              

irb(main):003:0> exit

ubuntu@ubuntuv:~/デスクトップ/projectX/blog$ rails s
```

サーバーを起動して、ちゃんとデータのタイトルが表示されればおっけ！

# 記事を1件表示する :feet: 

ルーティングファイルをいじる

```config/routes.rb
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
  root "articles#index"

  get "/articles", to: "articles#index"
  get "/articles/:id", to: "articles#show"

  # Defines the root path route ("/")
  # root "articles#index"
end
```

ここで重要な点がある、わかりやすい説明を引用した。

> 追加したルーティングも`get`ルーティングですが、パスの末尾に`:id`が追加されている点が異なります。これはルーティングのパラメータ（`parameter`）を指定します。ルーティングパラメータは、リクエストのパスに含まれる特定の値をキャプチャして、その値を`params`というハッシュに保存します。`params`はコントローラのアクションでもアクセスできます。たとえば`GET http://localhost:3000/articles/1`というリクエストを扱う場合、`:id`で`1`がキャプチャされ、`ArticlesController`の`show`アクションで`params[:id]`と書くとアクセスできます。
https://railsguides.jp/getting_started.html

次に`show`アクションを追加する

```app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end
end
```

`show.html.erb`を作成する

```html:app/views/articles/show.html.erb
<h1><%= @article.title %></h1>

<p><%= @article.body %></p>
```

これで、idに応じたタイトルと記事が表示できるようになります。
さらに、トップページからタイトルのURLを踏むと`show`ページに飛ばされるようにしましょう。

```html:app/views/articles/index.html.erb
<h1>Articles</h1>

<ul>
  <% @articles.each do |article| %>
    <li>
      <a href="/articles/<%= article.id %>">
        <%= article.title %>
      </a>
    </li>
  <% end %>
</ul>
```

`rails s`でサーバーを起動して、トップ画面から飛べたらOK！

# リソースルーティング :feet: 

自動でリソースとルーティングを紐づけることができるので、そっちを使おう！
ということでやっていく。

```config/routes.rb
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
  root "articles#index"

  #get "/articles", to: "articles#index"
  #get "/articles/:id", to: "articles#show"
  resources :articles

  # Defines the root path route ("/")
  # root "articles#index"
end
```

先ほどの`get ~`の部分をコメントアウトして、`resources :articles`とするだけで簡潔に書くことができる。

さらに、`app/views/articles/index.html.erb`のリンクの場所もより簡潔に書くことができる。

```html: app/views/articles/index.html.erb 
<h1>Articles</h1>

<ul>
  <% @articles.each do |article| %>
    <li>
      <%= link_to article.title, article %>
    </li>
  <% end %>
</ul>
```

`rails s`で問題なく動作していたら、OKですね！

# 記事を1件作成する :feet: 

記事を作成して、DBに書き込むページを作りましょう！

```app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(title: "...", body: "...")

    if @article.save
      redirect_to @article
    else
      render :new, status: :unprocessable_entry
    end
  end
end
```

書き込むようのページを作成

```html:app/views/articles/new.html.erb
<h1>New Article</h1>

<%= form_with model: @article do |form| %>
  <div>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </div>

  <div>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </div>

  <div>
    <%= form.submit %>
  </div>
<% end %>
```

`app/controllers/articles_controller.rb`の`create`メゾットを編集しましょう。
そして、`private`を追加する。

```app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      render :new, status: :unprocessable_entity
    end
  end

  private
    def article_params
      params.require(:article).permit(:title, :body)
    end
end
```

エラーがあった際に、メッセージを表示するようにしたい
その設定をしていきます！

```app/models/article.rb
class Article < ApplicationRecord
  validates :title, presence: true
  validates :body, presence: true, length: { minimum: 10 }
end
```

ポイントとしては以下の通り

> 1個目のバリデーションは、「titleの値が必ず存在しなければならない」ことを宣言している
2個目のバリデーションは、「bodyの値が必ず10文字以上存在しなければならない」ことを宣言している
https://railsguides.jp/getting_started.html （中略、一部改変）

`app/views/articles/new.html.erb`を編集して、エラーがあれば表示できるようにする！

```haml:app/views/articles/new.html.erb
<h1>New Article</h1>

<%= form_with model: @article do |form| %>
  <div>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
    <% @article.errors.fill_messages_for(:title).each do |message| %>
      <div><%= message %></div>
    <% end %>
  </div>

  <div>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
    <% @article.error.full_messages?for(:body).each do |message| %>
      <div><%= message %></div>
    <% end %>
  </div>

  <div>
    <%= form.submit %>
  </div>
<% end %>
```

仕上げとして、`index`から新規投稿できるようにリンクを貼りましょう！

```html:app/views/articles/index.html.erb
<h1>Articles</h1>

<ul>
  <% @articles.each do |article| %>
    <li>
      <%= link_to article.title, article %>
    </li>
  <% end %>
</ul>

<%= link_to "New Article", new_article_path %>
```

`rails s`で実行して、新規投稿できたらおっけですね！




# 参考にしたサイト :feet: 

https://railsguides.jp/getting_started.html