Rails6.0で作る交流会サイトの作成ログ

2019年8月20日

▼環境

Rails 6.0.0
Ruby 2.5.3

▼目標
コンパス見たいな勉強会・交流会サイトを作る。

▼目的
コーチング勉強会を募集するサイトを作って、参加者を管理できるようにしたい。また、シェアすることで同じようなサイトを作りたい人の参考にしてもらう

▼免責事項
本記事により発生した如何なる損害についても当方は責任をおいません。

▼進め方のルール
・コードの内容を説明したりしません。基本的にコピペで作れるようにして行きます。勉強したい人は、書いてあるコードをググルなりして理解をしてください。
・$ で書かれたところは、ターミナル
・コードの最初に#で書いてあるところは記載するファイル名
・Macで開発をしている前提で書いていきます。Windowsは知りません。

▼早速作って行こう!!!
環境構築を行っていない人は下記で行ってください。

$ xcode-select --install
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install rbenv
$ brew install ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv install 2.5.3
$ rbenv global 2.5.3
$ rbenv rehash
$ gem install bundler
$ gem install rails

もし、上記の環境構築でエラーが出たらググって調べてください。

次に、アプリを作っていきましょう!作成するアプリは、IT勉強会プラットフォームconnpassみたいなサイトです。同じように、コーチングのプラットフォームを作成していきます。
アプリ名は、コーチングの語源である乗合馬車から、riding-carriageにします。

$ rails new riding-carriage
$ cd riding-carriage
$ rails s

次に、ブラウザのURLに「http://localhost:3000」と入力して見ましょう!

ちゃんと、準備できましたね!このURL(ローカルホスト)を今後使って行くので、ブックマークして置いてください。

▼herokuへのデプロイ

インターネットに公開する作業をデプロイと言いますが、ちょいちょいデプロイするようにした方が修正が少なくてすみます。
無料で使えるherokuサーバーへデプロイしましょう。
herokuへのデプロイはこちらを参考にするといいと思います(めんどくさくなってきた・・・)
https://qiita.com/julia817/items/7908c01984a291b74966

ちなみに、私はなんか下記のようなエラーが出ました。

$ heroku logs
2019-08-20T05:26:56.850424+00:00 app[web.1]: Errno::ENOENT: No such file or directory @ rb_sysopen - tmp/pids/server.pid
2019-08-20T05:26:56.850426+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.12.1/lib/puma/launcher.rb:133:in `initialize'
2019-08-20T05:26:56.850428+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.12.1/lib/puma/launcher.rb:133:in `open'
2019-08-20T05:26:56.850430+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.12.1/lib/puma/launcher.rb:133:in `write_pid'
2019-08-20T05:26:56.850432+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.12.1/lib/puma/launcher.rb:106:in `write_state'
2019-08-20T05:26:56.850434+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.12.1/lib/puma/single.rb:103:in `run'

とりあえず、tmp以下にあるpidsの中に、sever.pidを作って、gitにあげたらエラーが解消されました。


さぁ、開発の準備ができたら、次は仕様を決めていきましょう!

▼MVP

・会員登録機能
・イベントの登録、管理機能
・イベントへの参加申し込み機能

※とりあえず、作ってから追加機能を考えます。

▼ワイヤーフレーム

こんな感じでワイヤーフレームを作りたいと思います。まぁ、デザインは適当で。というか、connpassのパクリで。

※他のページは適当に作ります。

▼早速作って行こう!

とりあえず、会員登録機能を作っていきましょう!
えーと、仕様としては、メールアドレスによる登録とSNS登録で。

ただ、フェイスブックもツイッターも、プライバシーポリシーの作成とか、申請して承認もらわないといけないとか面倒なんですよねー。

なので、準備だけしておいてあとで登録しときます。

Gemfileにomniauthを追記しましょう

# Gemfileに追記
gem 'omniauth'
gem 'omniauth-twitter' # ついでなのでtwitterも入れるだけ入れときます。
gem 'omniauth-facebook'
gem 'dotenv-rails', group: [:development, :test]
gem 'bcrypt', '~> 3.1.7'
gem 'image_processing', '~> 1.2'

はい、bundle

$ bundle

次に、omniauth使うよって設定をconfigに書きましょう。とりあえず、新しいファイル作ってかくといいと思います。omniauth.rbファイルを作りましょう。# config/initialize/omniauth.rb

# config/initialize/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
 provider :twitter, ENV['TWITTER_ID'], ENV['TWITTER_SECRET']
 provider :facebook, ENV['FACEBOOK_ID'], ENV['FACEBOOK_SECRET']
end

次に、.envファイルを作りましょう。その中に、変数を用意します。

# .env
TWITTER_ID=
TWITTER_SECRET=
FACEBOOK_ID=
FACEBOOK_SECRET=

ここに、諸々の手続きをしてもらってきたIDなどを入力してきます。

ちなみに、それぞれこちらから申請可能です。

なにはともあれ、メールアドレスによる会員登録機能を作っていきましょう!ちなみに、ユーザーの画像はactive storageを使ってアップロードするようにします。

$ rails g scaffold User name:string email:string uid:integer password_digest:string activation_digest:string introduction:text image:string 
$ rails active_storage:install
$ rails db:migrate

次に諸々編集していきます

# app/views/users/_form.html.erb
<%= form_with(model: user, local: true) do |form| %>
 <% if user.errors.any? %>
   <div id="error_explanation">
     <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

     <ul>
       <% user.errors.full_messages.each do |message| %>
         <li><%= message %></li>
       <% end %>
     </ul>
   </div>
 <% end %>

 <div class="field">
   <%= form.label "お名前" %>
   <%= form.text_field :name %>
   <% user.errors.full_messages_for(:name).each do |message| %><p style="color:red"><i><%= message %></i></p><% end %>
 </div>

 <div class="field">
   <%= form.label "メールアドレス" %>
   <%= form.text_field :email %>
   <% user.errors.full_messages_for(:email).each do |message| %><p style="color:red"><i><%= message %></i></p><% end %>
 </div>

 <div class="field">
   <%= form.label "パスワード" %>
   <%= form.password_field :password %>
   <% user.errors.full_messages_for(:password).each do |message| %><p style="color:red"><i><%= message %></i></p><% end %>
 </div>

 <div class="field">
   <%= form.label "パスワードの確認" %>
   <%= form.password_field :password_confirmation %>
 </div>

 <div class="field">
   <%= form.label "自己紹介" %>
   <%= form.text_area :introduction %>
   <% user.errors.full_messages_for(:introduction).each do |message| %><p style="color:red"><i><%= message %></i></p><% end %>
 </div>

 <div class="field">
   <%= form.label "画像" %>
   <%= form.file_field :image %>
   <% user.errors.full_messages_for(:image).each do |message| %><p style="color:red"><i><%= message %></i></p><% end %>
 </div>

 <div class="actions">
   <%= form.submit "新規登録" %>
 </div>
<% end %>
# app/models/user.rb
class User < ApplicationRecord
 before_save { email.downcase! }
 validates :name, presence: true, length: { maximum: 50 }
 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
 validates :email, presence: true, length: { maximum: 255 },
                   format: { with: VALID_EMAIL_REGEX },uniqueness:  { case_sensitive: false }
 validates :password, presence: true, length: { minimum: 6 }, confirmation: true, unless: :uid?, on: :create
 validates :image, presence: true
 has_one_attached :image

 has_secure_password

end
# app/views/users/index.html.erb
~省略~
<td><%= user.image %></td>
↓変更@
<td><%= image_tag user.image,style: "width:300px;" %></td>
~省略~

# app/views/users/show.html.erb
~省略~
<%= @user.image %>
↓変更
<%= image_tag @user.image,style: "width:300px;" %>
~省略~

コードを変更したら、実際に会員登録してみましょう!

http://localhost:3000 にアクセスし、「New user」から会員登録してみてください。

きちんと、会員登録ができました!

あっという間でしたね♪

次は、ログイン機能を作りましょう。

$ rails g controller sessions new
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
 def new
 end
 def create
   user = User.find_by(email: params[:session][:email].downcase)
   if user && user.authenticate(params[:session][:password])
     log_in(user)
     user.save
     redirect_to root_path,success:  "ログインに成功しました"
   else
     flash.now[:danger]="メールアドレスまたはパスワードが違います"
     render :new
   end
 end

 def destroy
   log_out
   @current_user = nil
   redirect_to root_path,success: "ログアウトしました。"
 end
end
# app/helpers/application_helper.rb
module ApplicationHelper

   def current_user
     @current_user ||= User.find_by(id: session[:user_id])
   end
   def logged_in?
     !current_user.nil?
   end

   # 記憶したURL (もしくはデフォルト値) にリダイレクト
   def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
   end

   # アクセスしようとしたURLを覚えておく
   def store_location
    session[:forwarding_url] = request.original_url if request.get?
   end

   def log_in(user)
     session[:user_id] = user.id
   end
   def log_out
     session.delete(:user_id)
     @current_user = nil
   end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
 include ApplicationHelper
 add_flash_types :success, :info, :warning, :danger
end
# config/routes.rb

Rails.application.routes.draw do
 resources :meetings
 root "users#index"
 resources :users
 get "/login" => "sessions#new"
 post "/login" => "sessions#create"
 delete "/logout" => "sessions#destroy"
end
# app/views/sessions/new.html.erb 
<h1>ログイン</h1>
<%= form_with(scope: :session, local: true,url: login_path) do |form| %>

 <div class="field">
   <%= form.label "メールアドレス" %>
   <%= form.text_field :email %>
 </div>

 <div class="field">
   <%= form.label "パスワード" %>
   <%= form.password_field :password %>
 </div>

 <div class="actions">
   <%= form.submit "ログイン" %>
 </div>
<% end %>

なんか作ってると、こちらに書くのを忘れそうなので、記載漏れがあったらすみません!

さて、次はイベント投稿機能を作っていきます。





サポートしていただけると、泣いて喜びます! 嬉しくて仕事をめちゃめちゃ頑張れます。