初めに
プログラミング学習初めて1ヶ月と少しですので、理解不足、誤りありましたらご指摘いただけますと幸いです。グループ作成機能②
①は別記事で記載しています。
この記事ではグループへの参加、退会ができるようにします。(ボタンで参加、退会ができるようにしています。)
グループの編集、更新については④の記事で説明しています。
また、グループ一覧画面で、グループ参加人数の表示と、グループ詳細画面でメンバー一覧を表示します。モデルファイル
モデルファイルはいじっていないので①の記事を参照ください。ルーティング記述
Rails.application.routes.draw do
devise_for :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root :to => "homes#top"
get "home/about" => "homes#about"
resources :books, only: [:index, :show, :edit, :create, :destroy, :update] do
resource :favorites, only: [:create, :destroy]
resources :book_comments, only: [:create, :destroy]
end
resources :users, only: [:index, :show, :edit, :update]
resources :groups do. #ここ!
get "join" => "groups#join"
end
end
①でdestroyの記述を作成していなかった(except: :destroyにしてた)ので、destroyもルーティングに含まれるようにしたのと、新たに join を追加しました。
コントローラーの記述
groups_controller.rb
class GroupsController < ApplicationController
before_action :authenticate_user!
before_action :ensure_correct_user, only: [:edit, :update]
def index
@book = Book.new
@groups = Group.all
end
def show
@book = Book.new
@group = Group.find(params[:id])
end
def join. #追記!
@group = Group.find(params[:group_id])
@group.users << current_user
redirect_to groups_path
end
def new
@group = Group.new
end
def create
@group = Group.new(group_params)
@group.owner_id = current_user.id
#追記しています!!!
@group.users << current_user
if @group.save
redirect_to groups_path
else
render 'new'
end
end
def edit
end
def update
if @group.update(group_params)
redirect_to groups_path
else
render "edit"
end
end
# 追記
def destroy
@group = Group.find(params[:id])
# current_userは、@group.usersから消されるという記述。
@group.users.delete(current_user)
redirect_to groups_path
end
private
def group_params
params.require(:group).permit(:name, :introduction, :image)
end
def ensure_correct_user
@group = Group.find(params[:id])
unless @group.owner_id == current_user.id
redirect_to groups_path
end
end
end
@group.users << current_user
この記述は、
@group.usersに、current_userを追加しているということなんですね。
Viewの記述
グループ一覧画面にメンバー数表示
views/groups/index.html.erb
# 該当部分のみ
<% @groups.each do |group| %>
<tr>
<td><%= attachment_image_tag(group, :image, :fill, 50, 50, fallback: "no-image-icon.jpg") %></td>
<td><%= link_to group.name, group_path(group) %></td>
<td><%= group.introduction %></td>
<td>
<%= group.users.count %>
</td>
メンバー数をどう取り出したら良いのやら..わからなかったのですが、
group.users.count
で取り出せます。countじゃなくてlengthでもいけると思います。
コントローラーのcreateアクションにある@group.users << current_user
の記述を忘れてしまうとグループ作成者がメンバーに含まれなくなってしまいます。
views/groups/show.html.erb
<div class='container px-5 px-sm-0'>
<%= render 'layouts/errors', obj: @book %>
<div class='row'>
<div class='col-md-3'>
<h2>User info</h2>
<%= render 'users/info', user: current_user %>
<h2 class="mt-3">New book</h2>
<%= render 'books/form', book: @book %>
</div>
<div class='col-md-8 offset-md-1'>
<h2>Group Detail</h2>
<table class='table table-hover table-inverse'>
<thead>
<tr>
<th></th>
<th>グループ名</th>
<th>紹介文</th>
<th>メンバー</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr>
<td><%= attachment_image_tag(@group, :image, :fill, 50, 50, fallback: "no-image-icon.jpg") %></td>
<td><%= @group.name %></td>
<td><%= @group.introduction %></td>
<td>
<% @group.users.each do |member| %>
<%= member.name %><br>
<% end %>
</td>
<td>
<% if @group.owner_id == current_user.id %>
<%= link_to 'Edit', edit_group_path(@group), class: "btn btn-sm btn-success" %>
<% elsif @group.users.include?(current_user) %>
<%= link_to 'Leave this group', group_path(@group), method: :delete, class: "btn btn-sm btn-danger" %>
<% else %>
<%= link_to 'Join this group', group_join_path(@group), class: "btn btn-sm btn-success" %>
<% end %>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>