はじめに
RoRがどんなものか試してみたかった。
雑ですが、また同じことを調べなくて済むようにメモ。
ちなみにsqliteもお初。
前提
Ubuntu 16.04
Ruby 2.4.1p111
Rails 5.2.3
Sqlite 2.4.1p111
プロジェクト作成
プロジェクト作成からscaffoldingまで。
## プロジェクト作成
$ rails new cafe
$ cd cafe/
## サーバ起動→http://localhost:3000でYay!が出ることを確認。
$ rails s
## 日記機能を生成
$ rails g scaffold diary title:string body:text
## scaffoldingした機能がURLマッピングされていることを確認
$ rails routes
## scaffoldingの結果を元にDBにテーブルを追加する
$ rails db:migrate
ちなみにscaffoldするときのstringは省略可能。デフォルトの型はstringのため。
DBにアクセスしてみる
"rails db"でDBコンソールにログインする。
### DBコンソール(sqlite)にログインする
$ rails db
### テーブル一覧を見てみる
sqlite> .tables
### テーブル定義を確認する
sqlite> .schema diaries
CREATE TABLE "diaries" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar, "body" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
### select結果にカラム名も出す
sqlite> .headers on
sqlite> .mode column
### SELECTしてみる
sqlite> SELECT * FROM diaries;
### sqliteコンソールを抜ける
sqlite> .quit
Viewをいじってみる
更新日時を追加してみる。ヘッダとかも日本語にする。
<p id="notice"><%= notice %></p>
<h1>日記一覧</h1>
<table>
<thead>
<tr>
<th>タイトル</th>
<th>本文</th>
<th>更新日時</th> <!-- 追加 -->
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @diaries.each do |diary| %>
<tr>
<td><%= diary.title %></td>
<td><%= diary.body %></td>
<td><%= diary.updated_at %></td> <!-- 追加 -->
<td><%= link_to '見る', diary %></td>
<td><%= link_to '編集', edit_diary_path(diary) %></td>
<td><%= link_to '削除', diary, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to '日記を新規作成する', new_diary_path %>
updated_atはscaffoldingの際に指定してないが、Railsが勝手に追加してくれる。
日付形式を変更する
最初はUTCになっているので、JSTに変更&表示形式も変更する。
JSTへ変更
config/application.rb へ
config.time_zone = 'Tokyo' を追加。
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Cafe
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.time_zone = 'Tokyo'
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
end
end
time_formats.rb の作成
以下を記入したconfig/initializers/time_formats.rbを作成する。
Time::DATE_FORMATS[:default] = "%Y/%m/%d %H:%M"
確認
再起動して更新日時が"%Y/%m/%d %H:%M"で表示されていることを確認。
scaffoldとは
参照・登録・編集・削除の機能を持つアプリの雛形を作成するジェネレータコマンド。
コマンド1つで必要なファイルを一括して作成してくれるのでとても便利だが、
これしか使わないとRailsがいつまでたっても理解できないので乱用はよろしくないってよく言われるらしい。他の言語でプログラミングとかMVCの基礎を学んでいる人は別にいいと思う。もちろんscaffoldを使わない方法も知る必要がある。
以下でコントローラから機能を作成する手順も載せる。
コントローラ生成からスタートして機能を作成する
コントローラの生成
usersコントローラとそれが持つindexアクションを生成。
コントローラだけでなくビューなどいろいろ生成されていることがわかる。
$ rails g controller users index
Running via Spring preloader in process 9407
create app/controllers/users_controller.rb
route get 'users/index'
invoke erb
create app/views/users
create app/views/users/index.html.erb
invoke test_unit
create test/controllers/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
生成されたコントローラ
class UsersController < ApplicationController
def index
end
end
以下の通り、処理がない場合は紐づくビューが呼ばれる。
Action Controller の概要 - 3 メソッドとアクション
ここでご注目いただきたいのは、newメソッドの内容が空であるにもかかわらず正常に動作するという点です。これは、Railsではnewアクションで特に指定のない場合にはnew.html.erbビューを描画するようになっているからです。
よって空のusers/indexアクションはapp/views/users/index.html.erbを返す。
※ちなみにerbは(embedded ruby)の略。
ルーティング追加
config/routes.rbにgetの2行を追加。usersとusers/indexにアクセスがあった場合はusersコントローラのindexアクションを実行するという意味。
Rails.application.routes.draw do
get 'users', to: 'users#index'
get 'users/index', to: 'users#index'
resources :diaries
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
modelの生成
タイヤ、エンジン、ハンドルを属性に持つ車モデルを定義。
モデルクラスとマイグレーションファイルが生成されている。
$ rails g model car tire:string engine:string handle:string
Running via Spring preloader in process 12514
invoke active_record
create db/migrate/20190329170956_create_cars.rb
create app/models/car.rb
invoke test_unit
create test/models/car_test.rb
create test/fixtures/cars.yml
作成されたモデルクラスcar.rbを見ると処理は記載されていないがこのクラスがあるだけでcarsテーブルにアクセスできるようになる。
マイグレーションの実行
Rails4まではrakeコマンドで行う必要があったが5からはrailsコマンドに吸収されたため以下のようにマイグレーションやroutesもrailsコマンドで実施できる。
$ rails db:migrate
== 20190329170956 CreateCars: migrating =======================================
-- create_table(:cars)
-> 0.0024s
== 20190329170956 CreateCars: migrated (0.0025s) ==============================
このあとrails dbコマンドでDBコンソールを開いてcarsテーブルが作成されていることを確認。
ERBの記述のルール
記号 | 動作 | サンプル |
---|---|---|
<% %> | コードとして実行 | <% if @test.present? %>Test<% end %> |
<%= %> | 変数の中身を出力 | <%= @test %> |
コントローラからビューへ変数を渡す
class UsersController < ApplicationController
def index
@test='テストだよ!!'
render template: 'users/index'
end
end
<h1>Users#index</h1>
<p><%= @test %></p>
<p><% if @test.present? %>test test test<% end %></p>
結果
Users#index
テストだよ!!
test test test
が画面に表示される。
デザインの変更
共通のレイアウトは以下のファイルで定義されている。
app/views/layouts/application.html.erb
ここに共通で適用したいcssとかjavascriptを設定してあげればOK。
ページごとにデザインを変えたい場合
assetを追加する
.users-index {
font-size: 20px;
}
alert('Hi user!');
のように、coffeeまたはscssを配置する。(ファイル名はassets.rbに指定する)
assets.rbのprecompileのコメントアウトを外す
指定するのはSprocketsによって変換された後のjs、css。
Rails.application.config.assets.precompile += %w( users.js users.css )
サーバを再起動してポップアップが出ることと、文字がおっきくなっていることを確認。
Sprocketsとは
coffeescriptやscssからJavascriptやcssを生成する仕組みを管理する。
ActiveRecordとは
Railsが採用するO/Rマッパー。
SQLを使用せずにDBにアクセスする。
rails g modelコマンドでActiveRecordによるモデルクラスを生成する。
このコマンドを使用するとテーブル作成SQLを実行するためのマイグレーションファイルも作成してくれる。
マイグレーションとは
テーブルの新規作成や変更を簡単に行うための仕組み。
DBMSによる違いを吸収して記述することができる。
以下はdiaryをg scaffoldした時のマイグレーションファイル。
timestampsはupdated_atなどのメタ情報。
class CreateDiaries < ActiveRecord::Migration[5.2]
def change
create_table :diaries do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
あとがき
ほんとはWindows+VSCodeで試したかったけど8年選手の低スペックマシンでは耐え切れなかったのでUbuntu16+Atomで試しました。
次は簡単なWEBページを作成してみようと思います。