これは、最新のRuby on Rails ガイド(v5.1.3) を読んだ際の学習記録です。
Getting Started with Rails — Ruby on Rails Guides
#1 Start Here
以下を学ぶ
- Railsインストール、Railsアプリケーションの作成、そしてアプリケーションをデータベースへ接続する方法
- 一般的なRailsアプリケーションのレイアウト
- MVC, RESTfulデザインの基本原則
- Railsアプリケーションを素早く生成する方法
What is Rails?
RailsはRubyで書かれたWebアプリケーションフレームワーク。Railsには以下の2つの重要な原則がある。
- Don’t Repeat Yourself
Don't repeat yourself - Wikipedia
Don’t repeat yourself (DRY) あるいはSingle Source of truth(英)[要出典]は、特にコンピューティングの領域で、重複を防ぐ考え方である。この哲学は、情報の重複は変更の困難さを増大し透明性を減少させ、不一致を生じる可能性につながるため、重複するべきでないことを強調する。
- Convention Over Configuration
設定より規約(せっていよりきやく、英: convention over configuration)とは、開発者の決定すべきことを減少させ、単純にするが柔軟性は失わせないというソフトウェア設計パラダイム。
Creating a New Rails Project
Creating the Blog Application
‘blog’ アプリケーションを生成する。
$ rails new blog
blog配下には以下のファイルを生成される。
- app/ Contains the controllers, models, views, helpers, mailers, channels, jobs and assets for your application. You’ll focus on this folder for the remainder of this guide.
- bin/ Contains the rails script that starts your app and can contain other scripts you use to setup, update, deploy or run your application.
- config/ Configure your application’s routes, database, and more. This is covered in more detail in Configuring Rails Applications. config.ru Rack configuration for Rack based servers used to start the application.
- db/ Contains your current database schema, as well as the database migrations.
- Gemfile
- Gemfile.lock These files allow you to specify what gem dependencies are needed for your Rails application. These files are used by the Bundler gem. For more information about Bundler, see the Bundler website.
- lib/ Extended modules for your application.
- log/ Application log files.
- public/ The only folder seen by the world as-is. Contains static files and compiled assets.
- Rakefile This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.
- README.md This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.
- test/ Unit tests, fixtures, and other test apparatus. These are covered in Testing Rails Applications.
- tmp/ Temporary files (like cache and pid files).
- vendor/ A place for all third-party code. In a typical Rails application this includes vendored gems.
- .gitignore This file tells git which files (or patterns) it should ignore. See Github - Ignoring files for more info about ignoring files.
Hello, Rails!
Starting up the Web Server
web serverを起動する。
$ cd blog $ rails server #shorthand: rails s
Say “Hello”, Rails
Railsで"Hello" を表示させるために、viewとcontrollerを生成する。
‘Welcome’ controllerの'index' アクションを生成する。
$ rails generate controller Welcome index
上記のgenerateコマンドで以下のファイル群が生成される。
create app/controllers/welcome_controller.rb route get 'welcome/index' invoke erb create app/views/welcome create app/views/welcome/index.html.erb invoke test_unit create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/welcome.coffee invoke scss create app/assets/stylesheets/welcome.scss
controllerは、app/controllers/welcome_controller.rb, viewはapp/views/welcome/index.html.erb へ生成された。
app/views/welcome/index.html.erb のh1タグを以下のように修正する。
<h1>Hello, Rails!</h1>
Setting the Application Home Page
Railsのroot を設定する。
config/routes.rb へ以下を追加する。
root 'welcome#index'
http://localhost:3000 へアクセスすると、Hello, Railsが表示される。
Getting Up and Running
CRUD操作を実現するためのresourceを定義する。
以下をconfig/routes.rb へ追加。
resources :articles
rails routes コマンドを実行すると、標準のRESTfulアクションが定義される。
$ rails routes Prefix Verb URI Pattern Controller#Action welcome_index GET /welcome/index(.:format) welcome#index articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PATCH /articles/:id(.:format) articles#update PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy root GET / welcome#index
Laying down the groundwork
生成した、http://localhost:3000/articles/new へアクセスしてみよう。'Routing Error'が出る。 これはrouteは生成したが、まだcontroller、viewが生成されてないため。
コントローラーを生成する。
$ rails generate controller Articles
生成した、app/controllers/articles_controller.rb を見てみよう。
class ArticlesController < ApplicationController end
ApplicationController を継承した、ArticlesControllerが定義されているが、まだ中には何も定義されていない。
この状態で先程のURIへアクセスしてみよう。
http://localhost:3000/articles/new
‘Unknown action’ エラーが出る。
app/controllers/articles_controller.rb を以下のように更新する。
class ArticlesController < ApplicationController def new end end
この状態で先程のURIへアクセスしてみよう。
http://localhost:3000/articles/new
‘ActionController::UnknownFormat in ArticlesController#new’ 今度は先程と別のエラーが出る。 viewがないためこのようなExceptionがなげられているため、次のviewテンプレートを新規作成する。
app/views/articles/new.html.erb
<h1>New Article</h1>
これでlocalhost:3000/articles/new へアクセスすると正常にページが表示される。
The first form
Railsのフォームビルダーは form_for と呼ぶヘルパーメソッドで提供される。
form_for: ActionView::Helpers::FormHelper
app/views/articles/new.html.erb へ以下を追加する。
<%= form_for :article 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 %>
生成されたhtmlを見ると、formのアクション属性が /articles/new を指している。 これを、/articles へ移動するように変更するため、form_forを以下のように書き換える。
<%= form_for :article, url: articles_path do |f| %>
ここで、rails routes コマンドでRailsのアクションを振り返ってみる。
$ rails routes Prefix Verb URI Pattern Controller#Action welcome_index GET /welcome/index(.:format) welcome#index articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PATCH /articles/:id(.:format) articles#update PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy root GET / welcome#index
POST /articles のアクションは create となっているため、画面のsave articleボタンを押すと ‘Unknown action’ エラーとなる。
Creating articles
‘Unknown action’ エラーを取り除くため、create アクションをコントローラへ追加する必要がある。
app/controllers/articles_controller.rb
class ArticlesController < ApplicationController def new end def create end end
このままだと 204 No Content エラーが出てしまう。 フォームがsubmitされるとパラメータがRailsに送信されるので、以下のようにして表示してみよう。
def create render plain: params[:article].inspect end
これで再度画面の'save submit' を押すと以下が表示される。title, text はformに入力した値が反映される。
<ActionController::Parameters {"title"=>"First Article!", "text"=>"This is my first article."} permitted: false>
Creating the Article model
次のコメンドでArticleモデルを生成する。モデルには単数形が使われる。
$ rails generate model Article title:string text:text Running via Spring preloader in process 12909 invoke active_record create db/migrate/20170815123358_create_articles.rb create app/models/article.rb invoke test_unit create test/models/article_test.rb create test/fixtures/articles.yml
このコマンドは、RailsにArticleモデルを共にstring型のtitle, text型のtextの属性を生成する。 これらの属性は自動的にarticlesテーブルに追加され、さらにArticleモデルにマッピングされる。
Active Recordは列名をモデル属性に自動的に対応させる。つまり、Railsモデル内で属性を宣言する必要はない。これは、Active Recordによって自動的に行われる。
Running a Migration
生成された db/migrate/20170815123358_create_articles.rb
class CreateArticles < ActiveRecord::Migration[5.0] def change create_table :articles do |t| t.string :title t.text :text t.timestamps end end end
次のコマンドで、articles テーブルを実際にデータベースへ生成する。
$ rails db:migrate
Saving data in the controller
ArticlesControllerへ戻り、submitしたデータをデータベースへ保存するためにcreateアクションを変更する。
app/controllers/articles_controller.rb
def create @article = Article.new(params[:article]) @article.save redirect_to @article end
実際に画面から'save article'を押すと ‘ActiveModel::ForbiddenAttributesError in ArticlesController#create’ エラーが表示される。 Railsが備えているセキュリティ機能が働いているため、コントローラーにどのパラメータが許可されているか伝える必要がある。
title と text を許可してみよう。
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
article_params は外部から意図せず呼ばれることを防ぐため、基本はprivateメソッドとして定義される。
Showing Articles
再度画面から、'Save Article'を押してみよう。すると、show アクションがないため以下のエラーが表示される。
Unknown action The action 'show' could not be found for ArticlesController
rails routes で確認。
$ rails routes ... article GET /articles/:id(.:format) articles#show
show アクションをコントローラへ追加しよう。
app/controllers/articles_controller.rb
def show @article = Article.find(params[:id]) end
続いてshowアクションのためのviewを追加する。
app/views/articles/show.html.erb
<p> <strong>Title:</strong> <%= @article.title %> </p> <p> <strong>Text:</strong> <%= @article.text %> </p>
再度画面から'Save Article'を押してみると、以下が画面に表示される。
Title: test title Text: test Text
Listing all articles
記事リストページを追加する。
$ rails routes 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> <td><%= link_to 'Show', article_path(article) %></td> </tr> <% end %> </table>
Adding links
記事のcreate, show, list が作成できたので、今度は記事へナビゲートするためのリンクを追加してみよう。
app/views/welcome/index.html.erb
<h1>Hello, Rails!</h1> <%= link_to 'My Blog', controller: 'articles' %>
link_to メソッドはRailsのview helperの1つ。articles へのリンクを生成する。
app/views/articles/index.html.erb の