2018年8月に行った、JavaとHTMLを軽くやったことのある、大学の後輩向けruby on rails勉強会で作った資料を横展開しました。
rails初心者が、一通りアプリを作成しリリースすることのできるので、誰かのためになればいいな〜という思い出Qiitaの記事にしました。
後半に向けて、だいぶ大雑把になっているのと、コメントにございますように不適切な面もございます。
時間を見つけ次第修正しますが、コメントまで拝見していただけると幸いです。
自分もrails初心者なので、間違っているところがあったらコメントでご指摘お願いいたします。
rubyの開発環境を準備しよう
rubyとは、まつもとゆきひろ氏(Matzさん)により開発されたオブジェクト指向スクリプト言語。
Javaみたいにコンパイルを行い実行するのではなく、そのまま実行することができる言語をスクリプト言語といいます。
ruby自体はオブジェクト指向なので、ほとんどJavaとできることは一緒です。
書き方がちょっと違うだけなので、rubyの書き方がわからない!ってなったら下記のサイトで検索してください。
1. rubyのインストール
今回はv2.5.0
のバージョンのrubyをインストールしてもらいます。
(ここからはMacの説明です。)
1. homebrewインストール
brew -v
でバージョン表示されなかったらhomebrewが入ってないのでいれましょう。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2. rbenvをインストール
rbenvは、rubyのバージョンを管理するツールです。
rubyが新しくなっても、いつでもバージョンを変えられるので、入れておきましょう。
brew install rbenv ruby-build
パスを通します。
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
インストールできたかの確認は
rbenv -v
でバージョン表示されるかです。
表示されなかったら読んでください!
3. rubyのインストール
rbenv経由でrubyをインストールします。
rbenv install 2.5.0
次に,どのバージョンのrubyを使うかを書きます。
rbenv local 2.5.0
ruby -v
で2.5.0
がでたらok
4. bundlerのインストール
bundlerは、特定のディレクトリ(フォルダ)に、ruby on railsで必要になるパーツたちを入れてくれる優しい子です。
この子は大切なので、入れておきましょう。
gem install bundler
ちなみにgemは、rubyのライブラリって思っておけば大丈夫です。
https://blog.codecamp.jp/rails-gem
次からが本番です。ruby on railsのアプリを作成して行きます!
参考記事
Qiita|MacにHomeBrew,rbenv,bundlerをインストールする
2. railsのアプリを作成しよう
ruby on railsとは、Rubyで構築された、Webアプリケーション開発のためのフレームワークです。
まっつさんが作った言語Rubyで、webアプリをえーかんじに作れる子って覚えてば大丈夫!
👇railsってどんな子?ってのが詳しく知りたい人へ
https://blog.codecamp.jp/what_is_rails
1. railsアプリ作りたいディレクトリに遷移
cd ディレクトリ名
みんな意外と自分がどこにいるか見失うので、pwd
って打ってみてください。
どこにいるかわかります。
2. Gemfileを作成
bundle init
3. Gemfileを書き換える。
Gemfileを下記のように書き換えます。
前: Gemfile
# gem "rails"
後: Gemfile
gem "rails", "~> 5.2.1" # 5.2.1以上5.3.0未満の最新のものを使用
4.必要なパーツをインストール
プロジェクトに必要なパーツをvendor/bundler
にぼこすか入れて行きます。
bundle install --path vendor/bundler
まぁまぁかかるので、待っててください。
今後gemってのを追加したら、bundle install
に入ります。
5. railsのアプリを入れる。
bundle exec rails new --skip-turbolinks --skip-test .
Overwrite /Users/YunaKato/takuten/practice_app/Gemfile? (enter "h" for help)
ってでるので、Enter。
6. railsのサーバーを起動
bundle exec rails server
これでhttp://localhost:3000/
をアクセスして「Yay! You’re on Rails!」が出たら、railsのアプリが無事起動しました!
みんなの疑問 「bundle execって何?」
おそらくProgateやった人は、rails new ファイル名
みたいなコマンドを打っていたと思います。
でも今回はbundle exec
を必ずrails
の前につけます。
なんでだと思いますか?
今までは、PC上に入っているrailsで実行していたんですが、
今回はvendor/bundle
内にいるrailsで実行しているんです。
なぜそれをした方が良いかというと、今後共同開発とかするようになると、「バージョン違い」ってのがおきたりします。
railsは割とバージョンに依存しているので、PCに入っているrailsで実行するのではなく、
プロジェクトごとのrailsを実行する必要があります。
なので、bundle exec
をつけることが大切です!!
もし、bundle exec
打つのめんどい!って人がいたら、エイリアスってのを設定するとbe rails
でbundle exec rails
って打てるようになるよ!!
(ちなみに私は git status
をgit st
にしたり、git checkout
をgit co
にしたりしています。)
3. ユーザー登録ができるようにしよう!
まずはじめに、ユーザー登録が必要な人は、ユーザー登録ができるようにしましょう!
ユーザー登録やログイン、パスワードの設定などは自分で書くと、結構セキュリティ面がダメになっちゃったりします。
そこで、今回はdevise というセッション周りを全部管理してくれる有能なパッケージを使います!
⚠︎ コメントにはございますように、最初のRailsアプリケーションを作成にはdeviseは向いていません。railsというフレームワークを理解した上で用いることが推奨されます。
かなり参考なサイト - [Rails] deviseの使い方
1. deviseをインストール
deviseはgemなんで、それをまずインストールします。
そのために、Gemfileに書き加えます。
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
# ↓追加
# Devise
gem 'devise'
書き加えたgemをインストールします。
bundle install
2. deviseをアプリ内に生成する。
先ほどのは、vendor/bundle
にdeviseをダウンロードしてきただけです。
まだアプリ内でdeviseを使える状態ではありません。
deviseをアプリ内で使うには、generate(生成)する必要があります。
下記コマンドを実行してdeviseを生成しましょう。
bundle exec rails g devise:install
そしたら、こんなのが出るはずです。
===============================================================================
Some setup you must do manually if you haven't yet:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
3. deviseの設定を行う。
先ほどのマニュアルの通りにセットアップを行なって行きます。
1. config/environments/development.rb にポート番号等を追記
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
2. home#indexをrootに設定
ここはprogateやった人ならできるはず!!!!!
自力で頑張ってみよう。
3. app/views/layouts/application.html.erbに警告やエラーを表示できるように書き換える。
<body>
<!-- ▼ 追加 -->
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<!-- ▲ 追加 -->
<%= yield %>
</body>
4. Deviseのviewを作成
下記deviseのコマンドを実行するだけで、必要なviewが生成されます。
bundle exec rails g devise:views
Userモデルの作成
今回はdevise経由でUserのモデルを作成します。
下記コマンドを実行すると、Userモデルを作成すると共に、ルーティングが自動に生成され先ほど作ったviewに結びつきます。
bundle exec rails g devise User
また、モデルを生成してもデータベースの貯蔵庫がいないので、DBをマイグレートして作成しましょう。
bundle exec rails db:migrate
こんな感じに表示されたら成功です。
== 20180720205705 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.0021s
-- add_index(:users, :email, {:unique=>true})
-> 0.0009s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0010s
== 20180720205705 DeviseCreateUsers: migrated (0.0043s) =======================
一度、ルーティングがどうなってるのかをみてみましょう。
下記コマンドで、ルーティングの設定がみることができます。
bundle exec rails routes
このように、サインインやサインアップなどができそうなルーティングがでてきたら成功です。
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
root GET / home#index
http://localhost:3000/users/sign_up
にアクセスすると、ユーザー登録できそうなフォームが表示されてると思います。
app/views/layouts/application.html.erb
に下記htmlを追加すると、セッション周りに必要なページに遷移できるように設定できます。
<body>
<!-- ▼ 追加 -->
<nav>
<% if user_signed_in? %>
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'サインアップ', new_user_registration_path %>
<%= link_to 'ログイン', new_user_session_path %>
<% end %>
</nav>
<!-- ▲ 追加 -->
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
Userにデフォルト以外のデータを保存できるようにしたい!
今回deviseを用いると,メールアドレスとパスワードが保存できるようになりますね。
でも、他に〇〇を登録させたいってこともあるでしょう。
そのような場合、どのようにすれば良いかをかいていきますね!
今回は、username
を登録できるようにします。
カスタマイズは自分自身でチャレンジしてみてください!
1. usernameを追加するマイグレーションファイルの作成
今回は、Userテーブルのにusernameというカラムを追加します。(何言ってるかわからない!ってなったら聞いて欲しいです!)
そのためには下記のコマンドを実行します。
bundle exec rails g migration AddColumnToUser username:string
すると、YYYYMMDD~~~~~_add_column_to_user.rb
が生成されると思います。
中をみてみると、
class AddColumnToUser < ActiveRecord::Migration[5.2]
def change
add_column :users, :username, :string
end
end
string型のusernameカラム(:username)をusersテーブル(:users)に追加するというコードが書かれてますね!
カラムを追加したり削除したりする時に参考になる記事
rails generate migrationコマンドまとめ
2. データベースに反映させる
migrationファイルを生成したあとは必ずデータベースをマイグレートします。
じゃないとDBに何も反映されません!
bundle exec rails db:migrate
そうすると、DBから反応が返ってきます。
== 20180720212254 AddColumnToUser: migrating ==================================
-- add_column(:users, :username, :string)
-> 0.0024s
== 20180720212254 AddColumnToUser: migrated (0.0025s) =========================
3. 登録できるようにコントローラを設定する。
/app/controllers/application_controller.rb
に下記のコードを追加
class ApplicationController < ActionController::Base
#### ▼ 追加 ###
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :username])
end
#### ▲ 追加 ###
end
ここに書いてあることはちょっとだけ難しいです。
なので、説明は割愛します。
before_actionに関して
rails: before_actionとは
permitに関して
【Ruby on Rails】require と permit の使い方がよく分からない
4. 登録できるようにビューを設定する。
せっかく登録できるようになったのに、それらを登録できるフォームを作らないと意味がないですね。
なので、usernameを登録できるフォームを/app/views/devise/registrations/edit.html.erb
と/app/views/devise/registrations/new.html.erb
に追加しましょう。
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<!-- ▼ 追加 -->
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true, autocomplete: "username" %>
</div>
<!-- ▲ 追加 -->
<div class="field">
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<!-- ▼ 追加 -->
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true, autocomplete: "username" %>
</div>
<!-- ▲ 追加 -->
<div class="field">
また、ログインしてる時は、ユーザーネームが表示されてるようにしましょう。
<nav>
<% if user_signed_in? %>
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'サインアップ', new_user_registration_path %>
<%= link_to 'ログイン', new_user_session_path %>
<% end %>
<!-- ▼ 追加 -->
<% if user_signed_in? %>
username : <%= current_user.username %>さん
<% end %>
<!-- ▲ 追加 -->
</nav>
4. ToDoリストの作成
今回はtodoリストということで、taskというモデルを作成します。
bundle exec rails g model task
YYYYMMDD~~~~_create_tasks.rbというマイグレーションファイルができるので、必要なデータをかいていきます。
class CreateTasks < ActiveRecord::Migration[5.2]
def change
create_table :tasks do |t|
# タイトル
t.string :title, null: false
# 説明
t.text :description, null: true
# 締め切り
t.datetime :target_at, null: true
# タスク完了日
t.datetime :completed_at, null: true
# タスク完了したか
t.boolean :completed, null: false, default: false
# userモデルのuser_idに結びつけるため、必要
t.references :user, foreign_key: true
t.timestamps
end
end
end
データベースをマイグレート。
bundle exec rails db:migrate
成功したら下記とおり表示されます。
== 20180720221424 CreateTasks: migrating ======================================
-- create_table(:tasks)
-> 0.0016s
== 20180720221424 CreateTasks: migrated (0.0017s) =============================
Userモデルクラス、Taskモデルクラスにアソシエーションの設定をします。
一つのuserが複数のタスクを持つことは可能であるため、「has_many」で関連付けします。
has_many関連付けは、他のモデルとの間に「1対多」のつながりがあることを示します。
app/models/user.rb
class User < ApplicationRecord
# ▼ 追加
has_many :tasks, dependent: :destroy
# ▲ 追加
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
一つのタスクは一つのユーザーに結びつくため、「belongs_to」で関連付けします。
「belongs_to」関連付けを行なうと、他方のモデルとの間に「1対1」のつながりが設定されます。
app/models/task.rb
class Task < ApplicationRecord
belongs_to :user, optional: true
end
タスクの一覧、詳細、新規作成、編集のページが欲しいので、作成。
bundle exec rails g controller tasks index show new edit
app/controllers/tasks_controller.rb
# 認証済みであることを確認
before_action :authenticate_user!
def index
@tasks = current_user.tasks
end
def show
@task = target_task params[:id]
end
def new
@task = Task.new
end
def create
@task = current_user.tasks.new task_params
@task.save!
redirect_to @task
end
def edit
@task = target_task params[:id]
end
def update
@task = target_task params[:id]
@task.update(task_params)
redirect_to @task
end
def destroy
@task = target_task params[:id]
@task.destroy
redirect_to tasks_url
end
private
def target_task task_id
current_user.tasks.where(id: task_id).take
end
def task_params
params.require(:task).permit(:title, :description)
end
app/views/tasks/index.html.erb
<h1>Tasks#index</h1>
<p>Find me in app/views/tasks/index.html.erb</p>
<table>
<tr>
<th>Id</th><th>Title</th><th>Description</th><th></th><th></th><th></th>
</tr>
<% @tasks.each do |task| %>
<tr>
<td><%= task.id %></td>
<td><%= task.title %></td>
<td><%= task.description %></td>
<td><%= link_to 'Show', task_path(task) %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Delete', task_path(task), method: :delete %></td>
</tr>
<% end %>
</table>
<p><%= link_to 'ToDoの作成', new_task_path %></p>
app/views/tasks/edit.html.erb
<h1>Tasks#edit</h1>
<p>Find me in app/views/tasks/edit.html.erb</p>
<div style="width: 300px;">
<%= form_for(@task) do |f| %>
<div>
<%= f.label :title %>
<%= f.text_field :title, size: 50 %>
</div>
<div>
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<%= f.submit 'Submit' %>
<% end %>
</div>
<p><%= link_to '一覧に戻る', tasks_url %></p>
app/views/tasks/new.html.erb
<h1>Tasks#new</h1>
<p>Find me in app/views/tasks/new.html.erb</p>
<div style="width: 300px;">
<%= form_for(@task) do |f| %>
<div>
<%= f.label :title %>
<%= f.text_field :title, size: 50 %>
</div>
<div>
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<%= f.submit 'Submit' %>
<% end %>
</div>
<p><%= link_to '一覧に戻る', tasks_url %></p>
app/views/tasks/show.html.erb
<h1>Tasks#show</h1>
<p>Find me in app/views/tasks/show.html.erb</p>
<table>
<tr>
<th>Title</th>
<td><%= @task.title %></td></tr>
<tr>
<th>Description</th>
<td><%= @task.description %></td>
</tr>
<tr>
<th>User.Email</th>
<td><%= @task.user.email %></td>
</tr>
</table>
<p><%= link_to '一覧に戻る', tasks_url %></p>
routingの設定をします。
今回は、リソースフルルーティングを用いて設定します。
リソースフルルーティングでは、CRUD(Create/Read/Update/Delete) 操作に対応付けられるルーティングを自動生成します。
resources :tasks
参考サイト
5. Herokuでリリース
1. herokuの登録
今回は、アプリとして使ってもらうため、serviceworkerを導入します。
また、Herokuはsqlite3が対応していないため、本番ではpostgresqlというデータベースを使います。
1-1. 下記リンクから登録
https://jp.heroku.com/
「welcome to heroku」が表示されたら、OK!!
1-2. PCにherokuいれる
(ターミナル or コマンドプロンプト)
brew install heroku
確認は
(ターミナル or コマンドプロンプト)
heroku --version
1-3. herokuをPCからログインする
(ターミナル or コマンドプロンプト)
heroku login
からの、emailとpassを入力
2. herokuアプリ作成
2-1. アプリ作成
(ターミナル or コマンドプロンプト)
heroku create [アプリ名]
git remote
-> herokuってでたらok
git remote
-> herokuって出ない -> git remote add heroku https://git.heroku.com/xxxxx-xxxxx-xxxxx.git(createした時にでてきた.gitのやつ)
2-2. Gemfile書き換え
(ターミナル)
brew install postgresql
(Gemfile)
gem 'sqlite3' # <- 削除
gem 'pg' # <- 追加
gem 'serviceworker-rails' # <- 追加
gem 'jquery-rails' # <- ない人追加
gem 'jquery-ui-rails' # <- ない人追加
group :development do
gem 'sqlite3' # <-こっちに追加
end
gemを再インストール
(ターミナル or コマンドプロンプト)
bundle install
3. serviceworkerを導入
3-1. インストール
(ターミナル or コマンドプロンプト)
bundle exec rails g serviceworker:install
3-2. いろいろ読み込ませる
production:
<<: *default
adapter: pg
database: db/production.pg
//
//= require jquery #ない人追加
//= require serviceworker-companion #追加
//= require rails-ujs
//= require activestorage
//= require_tree .
// safari起動させないための記述
$(function(){
$('a').click(function(){
location.href = $(this).attr('href');
return false;
});
});
<!-- headの中に書く -->
<link rel="manifest" href="/manifest.json" />
<meta name="apple-mobile-web-app-capable" content="yes"></head>
<link rel="apple-touch-icon" href="<%=image_path("icon.png")%>" />
Rails.configuration.assets.precompile += %w[serviceworker.js manifest.json]
/* iosがデフォルト明朝体なので変更 */
body {
font-family: 'Avenir','Helvetica Neue','Helvetica','Arial','Hiragino Sans','ヒラギノ角ゴシック',YuGothic,'Yu Gothic','メイリオ', Meiryo,'MS Pゴシック','MS PGothic'
}
3-4. manifestのカスタマイズ
{
"name": "appApp", #アプリの長い名前
"short_name": "app", #アプリの短い名前
"start_url": "/", #起動時のパス
"icons": [
{
"src": "<%=image_path("icon.png")%>", #アイコン
"type": "image/png",
"sizes": "192x192"
}
],
"theme_color": "#fbb03b", #テーマ
"background_color": "#9ce4ff", #起動時の色
"display": "fullscreen",
"orientation": "portrait"
}
4. herokuにリリース
4-1. git操作
git add .
git commit -m"〜〜〜〜"
4-2. herokuにpush
git push heroku master
4-3. herokuでデータベース構築
heroku run:detached rails db:migrate
4-4. herokuで作ったアプリ起動
heroku open