This request has already been treated.

  1. getty104
Changes in body
Source | HTML | Preview
@@ -1,885 +1,885 @@
2018年8月に行った、JavaとHTMLを軽くやったことのある大学の後輩向けruby on rails勉強会で作った資料メモの横展です。
rails初心者が、一通りアプリを作成しリリースすることのできるので、誰かのためになればいいな〜という思い出Qiitaの記事にしました。
後半に向けて、だいぶ大雑把になっていきます。
また、自分もrails初心者なので、間違っているところがあったらご指摘お願いいたします。
## rubyの開発環境を準備しよう
rubyとは、**まつもとゆきひろ氏(Matzさん)**により開発された**オブジェクト指向スクリプト言語**。
Javaみたいにコンパイルを行い実行するのではなく、そのまま実行することができる言語を**スクリプト言語**といいます。
ruby自体はオブジェクト指向なので、ほとんどJavaとできることは一緒です。
書き方がちょっと違うだけなので、rubyの書き方がわからない!ってなったら下記のサイトで検索してください。
[Ruby入門](https://www.rubylife.jp/ini/)
## 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](https://blog.codecamp.jp/rails-gem)
次からが本番です。ruby on railsのアプリを作成して行きます!
### 参考記事
[Qiita|MacにHomeBrew,rbenv,bundlerをインストールする](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b)
## 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
```rb
# gem "rails"
```
後: Gemfile
```rb
gem "rails"
```
### 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`にしたりしています。)
[【初心者向け】エイリアスの設定方法](https://qiita.com/yutat93/items/b5bb9c0366f21bcbea62)
## 3. ユーザー登録ができるようにしよう!
まずはじめに、ユーザー登録が必要な人は、ユーザー登録ができるようにしましょう!
ユーザー登録やログイン、パスワードの設定などは自分で書くと、結構セキュリティ面がダメになっちゃったりします。
そこで、今回は**devise** というセッション周りを全部管理してくれる有能なパッケージを使います!
かなり参考なサイト - [[*Rails*] deviseの使い方](https://qiita.com/cigalecigales/items/f4274088f20832252374)
### 1. deviseをインストール
deviseはgemなんで、それをまずインストールします。
そのために、Gemfileに書き加えます。
```rb
# 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/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に警告やエラーを表示できるように書き換える。
```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を追加すると、セッション周りに必要なページに遷移できるように設定できます。
```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`が生成されると思います。
中をみてみると、
```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コマンドまとめ](https://qiita.com/zaru/items/cde2c46b6126867a1a64)
#### 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`に下記のコードを追加
```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とは](https://qiita.com/weedslayer/items/c3ab7ad37d5a1e325989)
permitに関して
[【Ruby on Rails】require と permit の使い方がよく分からない](http://techblog.kyamanak.com/entry/2017/08/29/012909)
#### 4. 登録できるようにビューを設定する。
せっかく登録できるようになったのに、それらを登録できるフォームを作らないと意味がないですね。
なので、usernameを登録できるフォームを`/app/views/devise/registrations/edit.html.erb`と`/app/views/devise/registrations/new.html.erb`に追加しましょう。
```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">
```
```edit.html.erb
<% 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">
```
また、ログインしてる時は、ユーザーネームが表示されてるようにしましょう。
```application.html.erb
<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というマイグレーションファイルができるので、必要なデータをかいていきます。
```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.integer :user_id, null: true
+            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
+ belongs_to :user, optional: true
end
```
タスクの一覧、詳細、新規作成、編集のページが欲しいので、作成。
```
bundle exec rails g controller tasks index show new edit
```
app/controllers/tasks_controller.rb
```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
```html
<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
```html
<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
```html
<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
```html
<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
```
### 参考サイト
https://blog.freedom-man.com/rails-devise-todoapp/
## 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)
```ruby
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. いろいろ読み込ませる
```/config/database.yml
production:
<<: *default
adapter: pg
database: db/production.pg
```
```app/assets/javascripts/application.js
//
//= require jquery #ない人追加
//= require serviceworker-companion #追加
//= require rails-ujs
//= require activestorage
//= require_tree .
// safari起動させないための記述
$(function(){
$('a').click(function(){
location.href = $(this).attr('href');
return false;
});
});
```
```app/view/layouts/application.html.erb
<!-- 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")%>" />
```
```config/initializers/assets.rb
Rails.configuration.assets.precompile += %w[serviceworker.js manifest.json]
```
```app/assets/stylesheets/application.css
/* iosがデフォルト明朝体なので変更 */
body {
font-family: 'Avenir','Helvetica Neue','Helvetica','Arial','Hiragino Sans','ヒラギノ角ゴシック',YuGothic,'Yu Gothic','メイリオ', Meiryo,'MS Pゴシック','MS PGothic'
}
```
#### 3-4. manifestのカスタマイズ
```app/assets/javascripts/manifest.json
{
"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
```