Open1

コミュニティアプリの機能を学ぼう

かいかい

本好きのWebコミュニティ「Bookers2」の機能拡張に関するストーリーに基づいて、具体的な実装手順を示します。各課題に対する概要と実装ポイントを以下に示します。

課題 7c: グループ作成機能の実装

  1. グループモデルの作成:

    • グループを管理するためのモデルを作成します。モデル名は Group とします。
    rails generate model Group name:string owner:references
    
  2. 関連付けの追加:

    • User モデルと Group モデルの関連を設定します。User モデルに has_many :groupshas_many :group_memberships を追加します。
    • グループのメンバーシップを管理するための中間テーブル GroupMembership を作成します。
    rails generate model GroupMembership user:references group:references
    

ルーティングを忘れずに追加する

  resources :groups
  resources :group_memberships
  1. バリデーションの追加:

    • Group モデルに名前が存在することを確認するバリデーションを追加します。
    class Group < ApplicationRecord
      belongs_to :owner, class_name: 'User'
      has_many :group_memberships
      has_many :members, through: :group_memberships, source: :user
    
      validates :name, presence: true
    end
    
  2. グループ作成フォームのビューのコード作成:

    • ユーザーの一覧画面にグループ作成ボタンを追加し、グループを作成するためのフォームを作成します。
    user/index
    <!-- ユーザーの一覧画面 -->
    <%= link_to 'グループを作成', new_group_path %>
    
    group/new
    <!-- グループ作成フォーム -->
    <%= form_with(model: @group) do |f| %>
      <%= f.label :name, 'グループ名' %>
      <%= f.text_field :name %>
      <%= f.submit '作成' %>
    <% end %>
    
  3. グループ一覧画面の作成:

    • グループ一覧画面を作成し、自分がオーナーのグループには編集リンクを表示します。
    group/index
    <!-- グループ一覧画面 -->
    <% @groups.each do |group| %>
      <%= group.name %>
      <% if group.owner == current_user %>
        <%= link_to 'Edit', edit_group_path(group) %>
      <% end %>
    <% end %>
    
  4. グループ編集機能の実装を加えたコントローラー作成:

    • グループの編集画面を作成し、グループオーナーのみが編集できるようにします。
    • その他にもアクションを用意します(newとか)
groups_controller
class GroupsController < ApplicationController
   
  before_action :set_group, only: [:edit, :update]
  before_action :authorize_owner, only: [:edit, :update]

  def new
    @group = Group.new
  end

  def create
    @group = Group.new(group_params)
    @group.owner = current_user
    if @group.save
      redirect_to groups_path, notice: 'グループが作成されました。'
    else
      render :new
    end
  end

  def index
    @groups = Group.all
  end

  def edit
  end

  def update
    if @group.update(group_params)
      redirect_to groups_path, notice: 'グループが更新されました。'
    else
      render :edit
    end
  end

  private

  def set_group
    @group = Group.find(params[:id])
  end

  def authorize_owner
    redirect_to groups_path, alert: '権限がありません。' unless @group.owner == current_user
  end

  def group_params
    params.require(:group).permit(:name)
  end
end

課題 8c: グループ参加機能の実装

  1. グループ詳細画面の作成:

    • グループ詳細画面を作成し、ユーザーがオーナーでない場合に「Join this group」ボタンを表示します。
    class GroupsController < ApplicationController
      def show
        @group = Group.find(params[:id])
      end
    end
    
    group/show
    <!-- グループ詳細画面 -->
    <h1><%= @group.name %></h1>
    <% if @group.owner != current_user %>
      <%= button_to 'Join this group', group_memberships_path(group_id: @group.id), method: :post %>
    <% else %>
      <%= button_to 'Leave this group', group_membership_path(current_user.id, @group.id), method: :delete %>
    <% end %>
    
  2. グループ参加アクションの実装:

    • GroupMembershipsController を作成し、参加・退出機能を実装します。
    rails generate controller GroupMemberships create destroy
    
    class GroupMembershipsController < ApplicationController
      before_action :authenticate_user!
    
      def create
        @membership = GroupMembership.new(user: current_user, group_id: params[:group_id])
        if @membership.save
          redirect_to group_path(params[:group_id]), notice: 'グループに参加しました。'
        else
          redirect_to group_path(params[:group_id]), alert: '参加に失敗しました。'
        end
      end
    
      def destroy
        @membership = GroupMembership.find_by(user: current_user, group_id: params[:group_id])
        @membership.destroy if @membership
        redirect_to group_path(params[:group_id]), notice: 'グループから退出しました。'
      end
    end
    

課題 9c: イベント通知機能の実装

  1. イベント通知リンクの表示:

    • グループ詳細ページにグループオーナーのみが「Notice an Event」リンクを表示します。
    <!-- グループ詳細画面 -->
    <% if @group.owner == current_user %>
      <%= link_to 'Notice an Event', new_group_event_path(@group) %>
    <% end %>
    
  2. メール送信機能の実装:

    • イベント通知のためのメール作成画面を作成し、メールを送信するためのアクションを追加します。
    rails generate controller Events new create
    
    class EventsController < ApplicationController
      before_action :set_group
    
      def new
        @event = Event.new
      end
    
      def create
        @event = Event.new(event_params)
        @event.group = @group
    
        if @event.save
          GroupMailer.notify_members(@group, @event).deliver_now
          redirect_to group_path(@group), notice: '送信が完了しました。'
        else
          render :new
        end
      end
    
      private
    
      def set_group
        @group = Group.find(params[:group_id])
      end
    
      def event_params
        params.require(:event).permit(:title, :body)
      end
    end
    
  3. メール送信ロジックの実装:

    • GroupMailer を作成し、グループメンバーにメールを送信するメソッドを実装します。
    rails generate mailer GroupMailer
    
    class GroupMailer < ApplicationMailer
      def notify_members(group, event)
        @event = event
        @group = group
        mail to: group.members.pluck(:email), subject: "新しいイベント: #{@event.title}"
      end
    end
    

最後に

これらの実装を通じて、グループ機能やイベント通知機能をBookers2に追加できます。各機能の実装後は、動作を確認するためのテストを行うことも重要です。問題があれば教えてください!