sonoshouのまじめなブログ

情報系大学生からのウェブ見習い人生の記録

RailsGuildeをなぞってみた

本記事の目的

勉強の記録。
もし、検索してたどり着いた方がいらっしゃったら、本家を見た方が良いです。
RailsGuide

1. railsアプリケーションの作成

rails new blog

2. コントローラの作成

welcomeという名前のコントローラの中にindexというアクションを作成する。

  • controller:welcome
  • action:index

rails generate controller welcome index

createされるファイル

  • app/views/welcome
  • app/views/welcome/index.html.erb
  • test/controllers/welcome_controller_test.rb
  • app/helpers/welcome_hellper.rb
  • test/helpers/welcome_helper_test.rb
  • app/assets/javascripts/welcome.js.coffee
  • app/assets/stylesheets/welcome.css.scss

3. ルートの設定

アプリケーションのルートURLへのアクセスを welcomeコントローラのindexアクションに割り当てるようRailsに指示が伝わる。

  • controller:welcome
  • action:index

config/routes.rbに記入

root 'welcome#index'

Prefix コントール名#アクション名

フォーム

1. ルートの設定

config/routes.rbに記入

resources :articles

2. コントローラの作成

rails generate controller articles

createされるファイル

  • app/controllers/articles_controller.rb
  • app/views/articles
  • test/controllers/articles_controller_test.rb
  • app/helpers/articles_helper.rb
  • test/helpers/articles_helper_test.rb
  • app/assets/javascripts/articles.js.coffee
  • app/assets/stylesheets/articles.css.scss

app/controllers/articles_controller.rb

class ArticlesController < ApplicationController
end

3. コントローラの編集

newアクションの追加

def new
end

4. Viewの追加

app/views/articles/new.html.erb

<h1>New Article</h1>

5. フォーム

app/views/articles/new.html.erb

<%= form_for :article, url: articles_path do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

formの構文

form_for [シンボル名], [アクション名(prefix)] do |変数名|

6. 記事を作成する

app/controllers/articles_controller.rb

class ArticlesController < ApplicationController
  def new
  end

  def create
    render plain: params[:article].inspect
  end
end

renderメソッド

ハッシュのキー:plain ハッシュの値:params[:article].inspect

7. Articleモデルを作成する

rails generate model Article title:string text:text

Railsのモデル:単数形の名前 データベーステーブル名:複数形の名前

createされるファイル

  • db/migrate/[ts]_create_articles.rb
  • app/model/article.rb
  • test/models/article_test.rb
  • test/fixtures/articles.yml

8.マイグレーションを実行する

作成されたデータマイグレーションファイルを実行する。

rake db:migrate

デフォルトでは、development環境で実行される。 development以外の環境に対しては、

rake db:migrate RAILS_ENV=production

と明示的に指定する必要がある。

9. コントローラでデータを保存する

app/controllers/articles_controller.rb

def create
  @article = Article.new(article_params)

  @article.save
  redirect_to @article
end

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

10. 記事を表示する。

app/controllers/articles_controller.rb

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

app/views/articles/show.html.erb

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

記事の一覧表示

Controllerの編集

articles GET    /articles(.:format)          articles#index

が既にあるので、

app/controllers/articles_controller.rb

def index
  @articles = Article.all
end

ビューの追加

app/views/articles/index.html.erb

<h1>Listing articles</h1>

<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
  </tr>

  <% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
    </tr>
  <% end %>
</table>

リンクの追加

link_toメソッド

  • link_to [リンク先], [コントローラ]
  • link_to [リンク先], prefix

トップページにリンクを追加

app/views/welcome/index.html.erb

<%= link_to 'My Blog', controller: 'articles' %>

link_toメソッドは、指定されたテキストに基づいたリンクを作成し、ジャンプ先を表示する。

記事一覧からの記事新規作成リンク先

app/views/articles/index.html.erb

<%= link_to 'New article', new_article_path %>

記事作成からの戻るリンク先

app/views/articles/new.html.erb

<%= link_to 'Back', articles_path %>

検証(バリデーション)の追加

modelの更新

タイトルに対して、

  • すべての記事に存在
  • 長さが5文字以上

以上の検証を追加。

app/models/article.rb

class Article < ActiveRecord::Base
  validates :title, presence: true,
                    length: { minimum: 5 }
end

controllerの更新

modelだけの更新だと、検証の結果、保存に失敗しても、ユーザにはわからない。 失敗したことをユーザに伝えるためにcontrollerとviewを変更する。

app/controllers/articles_controller.rb

def new
  @article = Article.new
end

def create
  @article = Article.new(article_params)

  if @article.save
    redirect_to @article
  else
    render 'new'
  end
end

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

renderとredirect_to

  • render:フォームの送信時と同じリクエスト内で行われる
  • redirect_to:サーバに別途リクエストを発行するようにブラウザに指示する。

viewの更新

app/views/articles/new.html.erb

<%= form_for :article, url: articles_path do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', articles_path %>

解説

  • @article.error.any?:エラーがある場合、true
  • @article.error.count:エラーの数
  • @article.error.full_message:エラーメッセージの配列

記事の更新

controllerの編集

app/controller/articles_controller.rb

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

viewの追加

<h1>Editing article</h1>

<%= form_for :article, url: article_path(@article), method: :patch do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', articles_path %>

formの method: :patch でpatchであることがrailsに伝わる。

controllerの追加

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

  if @article.update(article_params)
    redirect_to @article
  else
    render 'edit'
  end
end

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

@article.update(article_params) とupdateメソッドを使う。

editアクションへの前記事のリンク

<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="2"></th>
  </tr>

<% @articles.each do |article| %>
  <tr>
    <td><%= article.title %></td>
    <td><%= article.text %></td>
    <td><%= link_to 'Show', article_path(article) %></td>
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
  </tr>
<% end %>
</table>

#

個別記事からの編集リンク

<%= link_to 'Edit', edit_article_path(@article) %>

パーシャルの利用

パーシャルとは?

テンプレート。重複を取り除くために使用する。 慣例として、パーシャルのファイル名の先頭には、 アンダースコア が使われる。

パーシャルファイルの追加

app/views/articles/_form.html.erb

<%= form_for @article do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

既存のviewファイルにパーシャルファイルを適用

app/views/articles/new.html.erb

<h1>New article</h1>

<%= render 'form' %>

<%= link_to 'Back', articles_path %>

app/views/articles/edit.html.erb

<h1>Edit article</h1>

<%= render 'form' %>

<%= link_to 'Back', articles_path %>

記事を削除する

controllerの編集

app/controllers/articles_controller.rb

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

  redirect_to articles_path
end

記事一覧ページに削除リンクを追加。

app/views/articles/index.html.erb

<td><%= link_to 'Destroy', article_path(article),
  method: :delete, data: { confirm: 'Are you sure?' }

オプション

  • :method:html5の機能。data-method="delete"
  • data-confirm:html5の機能。 data-confirm