質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

1267閲覧

Ruby on RailsでAjaxを利用して非同期で部分テンプレートのデータを変更する方法

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2017/11/01 22:54

編集2017/11/03 03:45

Ruby on RailsでAjaxを利用して非同期で部分テンプレートのデータを変更したいと考えております。
リロードすると変更されるのですが、部分テンプレートのボタンをクリックしただけでは、Ajaxが正しく動きません。
アドバイスなどしていただけますと幸いです。よろしくお願いいたします。
コードやデータベース設計は以下の通りです。

Ruby

1# ユーザーのモデルです 2User.rb 3# ユーザーが作成したチームです 4has_many :created_teams, class_name:Team, foreign_key: "owner_id", dependent: :destroy 5# ユーザーが参加したチームです 6has_many :participated_teams, through: :user_teams, source: :team 7# ユーザーとチームの中間テーブルのモデルです 8has_many :user_teams 9 10#「1つのチームには1回しか参加できない」というルール 11def participatable_for?(team) 12 team && !user_teams.exists?(team_id: team.id) 13end 14 15# 現在のユーザーがチームに参加していたらtrueを返す 16def participating?(team) 17 participated_teams.include?(team) 18end

Ruby

1# チームのモデルです 2Team.rb 3# チームを作成したユーザーです 4belongs_to :owner, class_name: "User" 5# チームに参加したユーザーです 6has_many :participants, through: :user_teams, source: :user 7# ユーザーとチームの中間テーブルのモデルです 8has_many :user_teams

Ruby

1# ユーザーとチームの中間テーブルのモデルです 2user_team.rb 3belongs_to :user 4belongs_to :team

Ruby

1# チームのコントローラーです 2TeamsController.rb 3 4def index 5 @teams = Team.order(created_at: :desc) 6end 7 8def show 9 @team = Team.find(params[:id]) 10end 11 12def edit 13 省略 14end 15 16def update 17 省略 18end 19 20def create 21 省略 22end 23 24def new 25 省略 26end 27 28def destroy 29 省略 30end 31 32# ユーザーをチームに参加させるアクションです 33def participate 34 @team = Team.find(params[:id]) 35 current_user.participated_teams << @team 36 respond_to do |format| 37 format.html 38 format.js 39 end 40end 41 42# ユーザーをチームから退会させるアクションです 43def unparticipate 44 @team = Team.find(params[:id]) 45 current_user.participated_teams.destroy(Team.find(params[:id])) 46 respond_to do |format| 47 format.html 48 format.js 49 end 50end 51 52private 53 54# ストロングパラメーター 55def team_params 56 params.require(:team).permit(:name) 57end

HTML

1teams/index.html.slim 2h2 チーム一覧 3.team-contents 4 - if @teams.present? 5 - @teams.each do |team| 6 article.team 7 h2 = team.name 8 .team-footer 9 .team-detail 10 # この部分テンプレートが以下のファイルです。 11 == render "participates", team: team 12 = link_to "詳細を見る", team, class: "more” 13 - else 14 p チームがありません。

ユーザーはグループに参加することが出来ます。退会することも出来ます。
以下の部分テンプレートのボタンをAjaxで切り替えて更新するのが目的です。
ボタンの動きはユーザーがチームに参加してる場合は「退会する」、参加していない場合は「参加する」ボタンを切り替えて表示するというものです。

HTML

1teams/_participates.html.slim 2#team-btn 3 - if current_user && current_user.participatable_for?(team) 4 = link_to "参加する", [:participate, team], method: :patch, class: "more", remote: true 5 - if current_user && current_user.participating?(team) 6 = link_to "退会する", [:unparticipate, team], method: :patch, class: "more", remote: true

HTML

1Team/participate.js.html 2$(“#team-btn”).html("<%= j(render ‘teams/participates') %>");

Ruby

1config/application.rb 2 3# 以下を追記 4config.action_view.embed_authenticity_token_in_remote_forms = true

Ruby

1config/routes.rb 2 3resources :users 4resources :teams do 5 member do 6 patch "participate", "unparticipate" 7 end 8end

部分テンプレートの「参加する」「退会する」というボタンを押すとAjaxで非同期でボタンを切り替えるのが目的です。
しかし、ボタンを押した後にブラウザをリロードしないとボタンが切り替わりません。

Turbolinksはオフにしています。
バージョンは以下の通りです。

Ruby: 2.3.1 Rails: 5.0.2

アドバイスなどよろしくお願いいたします。

<追記>
以下のように再実装したところチームの詳細ページ(show)では上手くAjaxで動くようになりました。
が、しかし上記に書いているチームの一覧ページ(index)では上手く動きません。なぜでしょうか?

HTML

1teams/index.html.slim 2h2 チーム一覧 3.team-contents 4 - if @teams.present? 5 - @teams.each do |team| 6 article.team 7 h2 = team.name 8 .team-footer 9 .team-detail 10 # この部分テンプレートが以下のファイルです。 11 #team-btn 12 - if current_user && current_user.participatable_for?(team) 13 == render "participates", team: team 14 - if current_user && !team.created_by?(current_user) && current_user.participating?(team) 15 == render "unparticipates", team: team 16 = link_to "詳細を見る", team, class: "more” 17 - else 18 p チームがありません。

Ruby

1#teams/_participates.html.slim 2 3= link_to "参加する", [:participate, team], method: :patch, class: "more", remote: true

Ruby

1#teams/_unparticipates.html.slim 2 3= link_to "退会する", [:unparticipate, team], method: :patch, class: "more", remote: true

Ruby

1#teams/participate.js.erb 2 3$("#team-btn").html("<%= escape_javascript render :partial => "teams/unparticipates" ,locals: {team: @team} %>");

Ruby

1#teams/unparticipate.js.erb 2 3$("#team-btn").html("<%= escape_javascript render :partial => "teams/participates" ,locals: {team: @team} %>");

上記のように実装しました所、以下のshowページでは上手くAjaxが動きました。

HTML

1teams/show.html.slim 2h2 チーム詳細ページ 3.team-contents 4 h2 = @team.name 5 # この部分が部分テンプレートです。 6 #team-btn 7 - if current_user && current_user.participatable_for?(team) 8 == render "participates", team: @team 9 - if current_user && current_user.participating?(team) 10 == render "unparticipates", team: @team

しかし、上記のteams/index.html.slimでは正しく動きません。
何か、アドバイスなどございましたら、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問