Help us understand the problem. What is going on with this article?

(メモ)【Rails勉強会 第8回】アソシエーンション Part2(2020/2/16)

※こちらの記事は,「人生逆転サロン共同開発参加者限定の勉強会」で使用したコードのメモ書きです。

人生逆転サロンの共同開発について知りたい方はこちらをご覧下さい。
http://yanbaru-spike.com/l/c/yE5eqgMh/NuSs3Jlb

0. 内容

【開催日】 2/16(日) 19:30〜20:30

前回,「1対多」のアソシエーションについての基礎を話しましたので,その実践として「ログイン機能付きのメッセージ投稿アプリ」を作成していきましょう!

1. ログイン機能の実装

1.1 アプリの作成

  • アプリの作成
ターミナル
rails new message_app

rails sでサーバーを起動し,http://localhost:3000にアクセスしたときに,Yay! You’re on Rails!が表示されることを確認して下さい。

1.2 ログイン機能の実装・日本語化

Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

gem 'rails', '~> 6.0.2', '>= 6.0.2.1'
gem 'sqlite3', '~> 1.4'
gem 'puma', '~> 4.1'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 4.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
gem 'bootsnap', '>= 1.4.2', require: false

# ***** 以下を追加 *****
# ログイン機能
gem 'devise'

# 日本語化(Rails 6の場合)
gem 'rails-i18n', '~> 6.0'
gem 'devise-i18n'
# ***** 以上を追加 *****

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  # ***** 以下を追加 *****
  # デバッグ用
  gem 'pry-byebug'
  # ***** 以上を追加 *****
end

group :test do
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  gem 'webdrivers'
end
ターミナル
# 必要があれば, $ cd message_app でアプリのルートディレクトリに移動後
bundle install
rails g devise:install
rails g devise user
rails db:migrate
config/application.rb
module MessageApp
  class Application < Rails::Application
    config.load_defaults 6.0
    # ***** 以下を追加 *****
    # 以下を追加すれば日本語に
    config.i18n.default_locale = :ja
    # ***** 以上を追加 *****
  end
end
  • サーバー「再」起動後に,http://localhost:3000/users/sign_upにアクセス

  • ログイン関連ページのビューファイル(見た目)を変更したい場合は,次のコマンドを使用してからファイルを修正

ターミナル
rails g devise:i18n:views
# 注意: 日本語のサイトを作るのに次を使用しないこと!
rails g devise:views
  • 日本語訳を変更したい場合は,次のコマンドを使用してファイルを修正
ターミナル
# 日本語訳を変更したい場合は,次でファイルを作成して編集
rails g devise:i18n:locale ja

【補足】 ログインページにフラッシュを実装したり,ユーザー編集ページなど修正した方がよい箇所があるが,今回はスルーで。

2. メッセージのCRUD機能

2.1 メッセージの一覧表示

ターミナル
rails g controller messages index new create edit update destroy
rails g model Message content:string user:references
  • バリデーションを入れておく
db/migrate/日時.rb
class CreateMessages < ActiveRecord::Migration[6.0]
  def change
    create_table :messages do |t|
      # ***** null: false を追加 *****
      t.string :content, null: false
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end
ターミナル
rails db:migrate
app/models/user.rb
class User < ApplicationRecord
  # ***** 以下を追加 *****
  has_many :messages, dependent: :destroy
  # ***** 以上を追加 *****
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
end
app/models/message.rb
class Message < ApplicationRecord
  belongs_to :user
  # ***** 以下を追加 *****
  validates :content, presence: true, length: { maximum: 140 }
  # ***** 以上を追加 *****
end
  • 初期データ

  • usersテーブル

id email
1 test@example.com
2 hoge@example.com
  • messagesテーブル
id user_id content
1 1 おはよう
2 2 こんにちは
3 1 こんばんは
4 1 おやすみ
db/seeds.rb
user1 = User.create!(email: "test@example.com", password: "password")
user2 = User.create!(email: "hoge@example.com", password: "password")

user1.messages.create!(content: "おはよう")
user2.messages.create!(content: "こんにちは")
user1.messages.create!(content: "こんばんは")
user1.messages.create!(content: "おやすみ")
ターミナル
rails db:seed
  • ルーティング
config/routes.rb
Rails.application.routes.draw do
  devise_for :users
  resources :messages
  root to: "messages#index"
end
  • コントローラ
app/controllers/messages_controller.rb
class MessagesController < ApplicationController
  # ***** 以下を追加 *****
  # ログイン必須とする
  before_action :authenticate_user!
  # ***** 以上を追加 *****

  def index
    # ***** 以下を追加(Message.allはよくない) *****
    @messages = Message.includes(:user)
    # ***** 以上を追加 *****
  end
end
  • ビュー
app/views/messages/index.html.erb
<% @messages.each do |message| %>
  <div>
    <p>【メールアドレス】 <%= message.user.email %></p>
    <p>【内容】 <%= message.content %></p>
  </div>
  <hr>
<% end %>

http://localhost:3000にアクセス

2.2 ヘッダー

app/views/layouts/application.html.erb
  <!-- 省略 -->
  <body>
    <!-- ***** 以下を追加 ***** -->
    <%= render 'shared/header' %>
    <!-- ***** 以上を追加 ***** -->
    <%= yield %>
  </body>
  • app/viewssharedディレクトリを作成
app/views/shared/_header.html.erb
<header>
  <% if user_signed_in? %>
    <%= link_to "投稿一覧", root_path %>
    <%= link_to "新規投稿", new_message_path %>
    <%= link_to 'アカウント編集', edit_user_registration_path %>
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
    <%= "【ログイン中のアドレス】#{current_user.email}" %>
  <% else %>
    <%= link_to "新規登録", new_user_registration_path %>
    <%= link_to "ログイン", new_user_session_path %>
  <% end %>
</header>
<hr>

2.3 メッセージの新規投稿機能

  • 投稿時のエラー処理は
app/controllers/messages_controller.rb
  # ***** 以下を編集 *****
  def new
    @message = Message.new
  end

  def create
    current_user.messages.create!(message_params)
    redirect_to action: :index
  end
  # ***** 以上を編集 *****

  # 略
  # ***** 一番下に以下を追加 *****
  private

  def message_params
    params.require(:message).permit(:content)
  end
  # ***** 以上を追加 *****
end
app/views/messages/new.html.erb
<%= form_with model: @message, local: true do |form| %>
  <%= form.text_field :content, required: true %>
  <%= form.submit "送信" %>
<% end %>

【補足】 本当はフラッシュを実装したり,投稿エラー時の処理が必要だが,今回はスルー

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした