やりたい事
Railsでアプリを作っているのですが、グループへの招待機能ってどう実装すれば良いんだ?と思い、考えてみました。
想定している仕様ですが、ユーザーは予めいくつかのグループを作成しており、ユーザーリストを見ながら「コイツいいじゃん!」って思ったユーザーを招待出来るようにします。
「どのユーザーをどのグループに招待するか」という組み合わせを取得する必要があります。
また、UIについてですが、ユーザー一覧に自分で作成したグループが表示されるセレクトボックスを設置し、ワンクリックで招待出来るようにしたいです。
送信ボタン等を押させたくないのでjavascriptでセレクトボックスの要素を取得して、get送信させる工夫が必要ですね。
準備
まずは、rails newしてアプリを作成して下さい。
rails new add_user --skip-bundle
jQuery追加
今回は、jqueryを使用します。
Gemfile.rb
にjqueryを追加します。
gem 'jquery-rails'
# bundle installも忘れずに!
bundle install
app/assets/javascripts/application.js
に下記を追加してjqueryを読み込む設定をします。
//= require jquery
ちなみにES6を勉強中なのでES6で書きたかったのですが、ネット上の資料が豊富なのでjqueryに頼ってしまいました・・・
Modelの作成
rails g model user name:string introduction:text
rails g model group name:string introduction:text admin_user_id:integer
rails g model add_user_to_group user_id:integer group_id:integer activation:boolean
booleanにdefault: falseとnull: falseを追加。
class CreateAddUserToGroups < ActiveRecord::Migration[5.2]
def change
create_table :add_user_to_groups do |t|
t.integer :user_id
t.integer :group_id
t.boolean :activation, default: false, null: false
t.timestamps
end
end
end
マイグレーションしましょう。
rake db:migrate
テストデータ追加
今回の説明では、ユーザー1が「フットサルサークル」、「写真部」、「ボードゲーム愛好会」というグループを作り、他のユーザーを招待するというケースを想定して説明します。
作成したモデルにテストデータを追加しましょう。
# rail consoleを開く
rails console
# User作成
User.create(name: 'ユーザー1', introduction: 'グループを作りました!!')
User.create(name: 'ユーザー2', introduction: 'フットサルが趣味です')
User.create(name: 'ユーザー3', introduction: '写真が好きです')
User.create(name: 'ユーザー4', introduction: 'ボドゲマニアです')
# Group作成
# admin_user_idはグループの作成者user_id。ユーザー1が下記の3つのグループを作った事にします。
Group.create(name: 'フットサルサークル', introduction: 'みんなでフットサルしましょう', admin_user_id: 1)
Group.create(name: '写真部', introduction: '写真を撮りに行きましょう', admin_user_id: 1)
Group.create(name: 'ボードゲーム愛好会', introduction: 'ボードゲームしましょう', admin_user_id: 1)
admin_user_id: 1となっていますが、実際にはグループ作成時にカレントユーザーのidを入れます。
テストなので、ユーザー1が作ったグループという事にします。
コントローラー作成
ユーザーのリストとグループへの招待機能を作ります。
下記を実行してコントローラーを作って下さい。
rails g controller Users index add_user_to_group
routes.rbも自動で下記のようになるはずなので、確認。
Rails.application.routes.draw do
get 'users/index'
get 'users/add_user_to_group'
end
コーディング作業
ユーザー1が自分のグループに他のユーザーを招待するというケースを前提に説明します。
まずapp/controllers/users_controller.rb
のindexに@users
、@group
を追加して下さい。
Groupは実際にはカレントユーザーが作成したグループを取得して実装します。
ユーザーの一覧から特定のユーザーを選び、自分が作成したグループに招待するためです。
class UsersController < ApplicationController
def index
@users = User.all
# テストなのでadmin_user_idに1を設定していますが、実際はcurrent_userのidを設定しましょう。
@groups = Group.where(admin_user_id: 1)
end
def add_user_to_group
end
end
app/views/users/index.html.erb
を下記のようにする。
グループ招待のセレクトボックスは自分以外のユーザーに表示します。自分で自分を招待する仕様はおかしいので。
ここでもuser.idが1じゃない時としてますが、実際はカレントユーザーのidを入れて、ログインしているユーザーと照合しましょう。
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<% @users.each do |user| %>
<p><%= user.name %>:<%= user.introduction %></p>
<!-- テストなので、user.idが1じゃない時にしてますが、実際はcurrent_userのidではない時に表示にしましょう -->
<% if user.id != 1 %>
<select class='group' id=<%= "#{user.id}" %>>
<option value="0">グループへ招待</option>
<% @groups.each do |group| %>
<option value=<%= "#{group.id}" %>><%= "#{group.name}" %></option>
<% end %>>
</select>
<% end %>
<hr>
<% end %>
この時点でrails s
してlocalhost:3000/users/index
にアクセスすると下記の画面になるはずです。
ユーザー1がログインして、他のユーザーをグループへ招待するというテストケースです。
ユーザー1以外のユーザーには、ユーザー1が作ったグループのセレクトボックスが追加されています。
グループへの招待機能
セレクトボックスで選択したユーザーのidとグループのidを動的にget送信します。送信した後にコントローラーでユーザーとグループの組み合わせを招待情報として保存します。
js記述とget送信
先程のviewにjavascriptを追加します。viewにjavascriptをベタ書きするのは、本当は良くないのですが、筆者の体力もそろそろ限界のため、一旦ここに書いて動作確認とQiitaへのアウトプットをさせて下さい!
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
# ここから
<script>
$(function() {
// groupクラスの変更を検知する
$('.group').change(function() {
$.ajax({
// getしたいurl
url: "/users/add_user_to_group",
// 送信形式にget設定
type: "GET",
// パラメーターにuser_idとgroup_idを追加して、コントローラーへ渡す
data: { user_id: $(this).attr('id'), group_id: $(this).has('option:selected').val() }
});
// グループへ招待したら、画面上からグループを消す。
$(this).children('option:selected').remove();
});
});
</script>
# ここまで追加
<% @users.each do |user| %>
<p><%= user.name %>:<%= user.introduction %></p>
<!-- テストなので、user.idが1じゃない時にしてますが、実際はcurrent_userではない時に表示にしましょう -->
<% if user.id != 1 %>
<select class='group' id=<%= "#{user.id}" %>>
<option value="0">グループへ招待</option>
<% @groups.each do |group| %>
<option value=<%= "#{group.id}" %>><%= "#{group.name}" %></option>
<% end %>>
</select>
<% end %>
<hr>
<% end %>
ユーザーとグループの組み合わせをDBに保存
パラメーターで、user_id
とgroup_id
が渡ってきているので、add_user_to_group
にて招待データを登録します。
AddUserToGroup
にuser_id
とgroup_id
を登録する事で、どのユーザーが、どのグループに招待されているかわかるはず!
あとは、招待されたユーザー側の機能で、activation
カラムをtrueにしたら正式にグループ参加する仕様で良いかな。
class UsersController < ApplicationController
def index
@users = User.all
# テストなのでadmin_user_idに1を設定していますが、実際はcurrent_userのidを設定しましょう。
@groups = Group.where(admin_user_id: 1)
end
# 以下を追加
def add_user_to_group
AddUserToGroup.create(user_id: params[:user_id], group_id: params[:group_id])
end
end
見辛いですけど、user_id
とgroup_id
の組み合わせがちゃんと入ってますね!
とりあえずここまで。
改善点
今回、jQuery使っちゃいましたが、本当はES6勉強してるので、ES6で書きたいです。
JavaScript(ES6)の基本文法まとめ
JavaScript(ES6)の関数、オブジェクト、クラスのまとめ
あと、jQueryに関してなんですが、過去資料がかなり豊富なのに最近の記事は少ない感じがしました。
ブームが去ったという事でしょうか。
実務でもjQueryよりReact、Vue.jsを使いそうなので、フレームワークで実装出来るようにしたいですね。