目的
スポーツを絡めたアプリを作成中。
そのアプリ内にて試合後一緒にプレイした他の選手に対して評価が出来るシステムを設けたいがユーザーファーストで考えて、form_forもしくはform_tagを使用して評価を行うページは一つにまとめたい。
と既に存在するレコードに対してのリファレンスが多くみられた。
他にもajaxを使って非同期にてcreateも考えた
ajax設備
が冗長になる事も考えて別の方法を探索。
今回採用した手法
と、上のリンクを参考にプログラムしてみたが纏まりきらないので皆様のお力を貸して下さい!!
ソースコード
evaluations#new
erb
1 <% n=1 %> 2 <% @evaluated.each do |member|%> 3 <%= form_for @evaluation , html: {id: "form#{n}"} do |f| %> 4 <%= f.hidden_field :game_id, value: @game.id %> 5 <%= f.hidden_field :evaluator_id, value: current_member.id %> 6 <%= f.hidden_field :evaluated_id, value: member.id %> 7 <div class="m-3"> 8 <h3><%= member.name %>さんへの評価</h3> 9 <div class="star"></div> 10 <div class='form-team'> 11 <%= f.text_field :comment, class:'contact-form text-white', placeholder: "コメント" %> 12 </div> 13 </div> 14 <% end %> 15 <% n+=1 %> 16 <% end %> 17 <span id="count" style="display:none;"><%= @evaluated.count%></span> 18 <div class="actions text-center"> 19 <input value="送信する" type="submit" id="send_evaluation" class="btn btn-lightblue text-center"> 20 </div> 21 22</div> 23 24<script> 25$('.star').raty({ 26 size : 36, 27 starOff: '/assets/star-off.png', 28 starOn : '/assets/star-on.png', 29 scoreName: 'evaluation[stars]' 30}); 31var button = document.getElementById('send_evaluation'); 32var n = document.getElementById('count').textContent; 33console.log(n); //デベロッパーツールのデバッグ用 34button.onclick = function(){ 35 for(var i=1; i<n; i++){ 36 console.log(i); //デベロッパーツールのデバッグ用 37 setTimeout(function(){ 38 var f = document.getElementById("form"+ i); 39 console.log(f); //デベロッパーツールのデバッグ用 40 f.submit();}, 300*i); 41 } 42}; 43</script>
evaluation model
def new @evaluation = Evaluation.new @game = Game.find(params[:game_id]) @count = @game.game_members.count-1 others = GameMember.where(game_id: @game, evaluation: false).where.not(member_id: current_member).pluck(:member_id) @evaluated = [] others.each do |m| member = Member.find(m) @evaluated.push(member) end end def create @evaluation = Evaluation.new(evaluation_params) if @evaluation.save redirect_to game_path(evaluation_params[:game_id]), success: "評価が完了しました" else reder "new" end end private def evaluation_params params.require(:evaluation).permit(:game_id, :evaluator_id, :evaluated_id, :stars, :comment) end
###手法
たとえば4人で行うスポーツだったら他三人を評価します。
スポーツ自体大人数でやる競技ではないのですが、今後チーム戦も考えて20人でひとくくりもあり得ます。
アソシエーションの関係で試合テーブルとユーザーテーブルの間にGameMemberテーブルが存在します。
each文で回した分n+1をしていき、それをformのidに指定しております。
javascriptではnの最大値を取得しfor文で同じ数増やしていき、一つ前ののフォームから300*iだけ遅れて送信したいと考えました。
上の様な位置にデバッガーを配置して一つずつ進めると、コンソールにて、setTimeOutのイベントに入る前にfor文が全て実行されていることが判明し、イベントに入ってきた時点でi==2となってしまいます。
for文の条件式も、1ループずつsetTimeOutiイベントに入っていったと仮定して (var=1; i==n;i++) にしたいのですがこちらにした途端送信ボタンが反応しません。
どこが原因なのかご教授お願いしたいです。
また、evaluations#createアクションで@evaluation.saveの場合リダイレクトする処理を条件分岐でおいてますが、複数のレコードを秒差で送信する今回の処理の場合うまく動くのでしょうか。
こちらもご教授下さい。
みなさま宜しくお願いします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/29 00:54