2020年5月13日水曜日

簡易SNSを作ってみよう(13)

ページ参照を用いた「新規投稿」の表示
Teacherロールでログインしたときに,参照記録を辿って,ページを参照した日時よりも新しい投稿があった場合には,配列@updated_usersに入れるようにする

【手順】
vi app/contorollers/users_controller.rb
(以下を追記)
 def show
   @user = User.find(params[:id])
   #@students = ... 削除
   @posts = Post.where(user_id: @user.id).order('created_at desc')

   visit = current_user.visits.find_by(visitee: @user.id)
   if (visit != nil)
     visit.touch
   else
     current_user.visits << Visit.create(visitee: @user.id)
   end

   if @user.role == 'teacher' then
     @students = User.where(role: 'student').order('updated_at desc')
     @updated_users = []
     current_user.visits.each {|v|
       st = @students.find_by(id: v.visitee)
       next if st == nil
       @updated_users.push(st.id) if \
(Post.where(user_id: v.visitee)
            .where(updated_at: v.updated_at ... Time.now).size > 0)
     }
   end
 end

さらに,Viewも変更し,@updated_usersのユーザーは警告色で表示されるようにする.

【手順】
vi app/views/users/show.html.erb
(以下を修正)
<h1>MyPage for <%= @user.fullname %></h1>
<% if @students != nil %>
  <p>
   <% @students.each {|st|
      color = @updated_users.include?(st.id) ?
        'btn btn-warning' : 'btn btn-light' %>
   <%= link_to st.fullname, user_path(st.id), class: color %>
   <% } %>
  </p>
<% end %>
…(略)…

初期データとしてTeacherロールによるVisitを作成しておく必要があるため,db/seeds.rbを修正して,データを再構築する(以下はローカルのサーバを想定.Herokuの場合は後述の手順で実施すること).
vi db/seeds.rb
(以下を追記)
names.each_with_index {|name, i|
  uid = sprintf "user%03d", i
  User.create(username: uid, fullname: name, password: '123456', 
                role: ((i == 0) ? 'teacher' : 'student'))
  Visit.create(user_id: 1, visitee: (i+1))
}

bin/rails db:drop
bin/rails db:create
bin/rails db:migrate
bin/rails db:seed
「新規投稿」の確認
サーバを起動し,Studentロールの適当なアカウントでログインしたのち幾つかのコメントを投稿してみる.しかるのちに,Teacherロールのアカウント(user000)でログインして,新規投稿のあるユーザーがハイライト表示されていることを確認する.

「新規ユーザー」の対応
ところで,この実装だと,新規ユーザーを作成し,そのユーザーが投稿したときに,うまくハイライト表示にならないという問題がある.なぜならば,ハイライト表示させるかいなかを,投稿がポストされた時刻とVisitエントリの比較で判断しているが,新規ユーザーにはVisitの記録がないためである.そこで,新規ユーザー登録されたときに,TeacherロールでダミーのVisitが行われるように,処理を追加する.

【手順】
vi app/controllers/users/registrations_controller.rb
(以下の該当部分をコメントアウトして追記)
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  before_action :configure_account_update_params, only: [:update]

  # GET /resource/sign_up
  # def new
  #   super
  # end

  # POST /resource
  def create
    super
    teachers = User.where(role: 'teacher')
    teachers.each {|t|
      t.visits << Visit.create(visitee: current_user.id)
      # 上は Visit.create(user_id:t.id, visitee:current_user.id) と同じ
    }
  end

…(略)…
動作確認
サーバを起動し,新規ユーザー登録,そのユーザーで投稿する.一度ログアウトしてTeacherロールのユーザー(user000)でログインしなおして,該当ユーザーがハイライト表示されていることを確認せよ.

0 件のコメント:

コメントを投稿