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

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

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

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

Ruby on Rails

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

Ajax

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

Q&A

解決済

2回答

1890閲覧

Ruby on Rails remote:true Ajaxを用いて非同期通信について

atage517

総合スコア36

Ruby

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

Ruby on Rails

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

Ajax

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

0グッド

0クリップ

投稿2020/08/05 23:58

編集2020/08/06 07:33

わからないこと

こちらのサイトではajax を用いて非同期通信を行う際に remote: true に加えて app/views/likes/create.js.erb ファイルなるものを作成し、その中にJSのコードをかく?とういうことをして remote: true の非同期通信を可能にしているみたいですが。

<%= link_to("/likes/#{@post.id}/create", method: "post", remote: true ) do %> <i class="fas fa-thumbs-up"></i> class LikesController < ApplicationController before_action :authenticate_user def create @like = Like.new( user_id: @current_user.id, post_id: params[:post_id] ) @like.save redirect_to("/posts/#{params[:post_id]}") end end

自分のコードではhtml に remote: true と書くだけでも非同期通信はできるのですがこれはローカルだからでしょうか?本番環境で実行しようとするとうまくいかないのでしょうか? ajax での非同期通信については昨日知ったばかりなので詳しいことはまだわかりませんが remote: true とだけ書くことで実行可能なのでしょうか?

やったこと

posts#show    <div id="likes_buttons_<%= @post.id %>"> <i class="fas fa-bookmark"></i> <%= render partial: 'likes/like', locals: { post: @post, likes: @likes} %> </div>
_like.html.erb <% if @post.user_id != @current_user.id %> <% if Like.find_by(user_id: @current_user.id, post_id: @post.id)%> <%= link_to("/likes/#{@post.id}/destroy", method: "post", remote: true) do %> <i class="fas fa-bookmark unclip"></i> <% end %> <% else %> <%= link_to("/likes/#{@post.id}/create", method: "post", remote: true ) do %> <i class="fas fa-bookmark"></i> <% end %> <% end %> <%= Like.where(post_id: @post.id).count %> 回答: <%= Answer.where(post_id: @post.id).count %>件 <% else %> <i class="fas fa-bookmark"></i> <%= Like.where(post_id: @post.id).count %> 回答: <%= Answer.where(post_id: @post.id).count %>件 <% end %>
create.js.erb $('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>");

参考にしたサイト

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

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

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

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

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

guest

回答2

0

ベストアンサー

自分のコードではhtml に remote: true と書くだけでも非同期通信はできる

app/views/likes/create.js.erbを用意していなくとも動いている」という意味だと思いますが、

rb

1# LikesController#create 2redirect_to("/posts/#{params[:post_id]}")

コントローラでリダイレクトしているのでremote: trueがあろうが無かろうが同じような動きをします。
仮に、ここでリダイレクトされていない場合にapp/views/likes/create.js.erbを見に行くのでこのファイルが必須となります。

そもそも非同期処理は、「ページ遷移を行わず画面の一部を変更する」ために用いられるものですので、そのためにはJavaScriptが必須となります。今回の場合は画面遷移を伴うので非同期処理である必要はありません。

投稿2020/08/06 02:02

編集2020/08/06 02:05
Mugheart

総合スコア2349

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

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

atage517

2020/08/06 02:14

なるほど、redirect_toでページ遷移を行なっているためにページのリロードはされないが、いいねを押した時に画面の上に飛んでしまう。 これをrenderにすればいいのですかね?だから参考にしたwebサイトが全てrenderなのかと勝手に納得したんですが。 現状としてはremote: true → redirect_to なのでページのリロードはされないが例えばページの途中でいいねをするとページの上に飛ばされてしまいます。これをリロードもせずにかつページの上に飛ばされないようにもしたいと思っています
Mugheart

2020/08/06 02:18

> これをrenderにすればいいのですかね?だから参考にしたwebサイトが全てrenderなのかと勝手に納得したんですが。 違います。というか参考にされているサイトでもコントローラにrenderは書かれてないでしょう? 回答にも書いた通り、redirect_toしなければapp/views/likes/create.js.erbを見に行くので、そこにJavaScriptのコードを書いてHTMLの特定の要素を書き換えます。
atage517

2020/08/06 02:47

なるほど!そもそもcontroller に書かなくていいということですね。 .box_button_like #like-button-zone{ id: user.id } -# userのidが1の場合、id="like-button-zone_1"になります = render partial: "likes/like", locals: { user: user } viewにはrenderと書かれていますがこれはcontrollerのrenderとは違うんでしょうか?
atage517

2020/08/06 03:27

そうなんですね。それは知りませんでした。自分でも深く調べてみます。ありがとうございます!
guest

0

同じことで悩んで、自己解決したことがあるのですが、前提としてpost側とget側で分けて考えると良いかと思います。

https://teratail.com/questions/238976#reply-352560
ここらへんの内容をRailsGuideなどでもっとわかりやすく書いてもらえるといいなと思っています。

投稿2020/08/06 01:34

no1knows

総合スコア3365

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

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

atage517

2020/08/06 02:50

no1knowsさん 参考先のサイトを拝見しました。自分がやりたいこととしてはlike の post のみなのでgetは考えなくていいのかな?と思いました。 あと参考のサイトにもあるように // いいね残高をコントローラにて定義した@sending_userを用いて表示します $(".like_balance").html("<%= @sending_user.like_balance %>") htmlをcreate.js に書き換えるこの書き方がいまいち不明です。 jquery の htmlを変えるコマンドでruby風に変えているということでしょうか?
no1knows

2020/08/06 05:59 編集

atage517さんのサンプルを基に凄いシンプルに説明すると下記のような形になるかと思います。 ・いいねを押したら、いいねの色や形だけが変わる or いいねの数だけが増える  ⇒postのAjaxを使いましょう ・いいねを押したら、画面遷移(画面が白くなったり)してから、いいねの色や形だけが変わる or いいねの数が増える  ⇒getは気にしなくていいです。 もしイメージがつかなければ、「Ajaxとは」で検索するか、Railsガイドの「Rails で JavaScript を使用する」の「4.サーバー側で考慮すべき点のシンプルな例」を実装するととてもイメージがつきやすいです。←個人的に凄いおすすめです。
no1knows

2020/08/06 03:40

> htmlをcreate.js に書き換えるこの書き方がいまいち不明です。 これは、create.js.erbという名称に変更することがわからないということでしょうか? それとも$(".like_balance").html("<%= @sending_user.like_balance %>")のコードが何をしているかがわからないということでしょうか? もし後者なら、その後の説明を読んでいただくと良いかと思いますが、jQueryのhtml()メソッドで、like_balanceクラスの文字を変更しています。
Mugheart

2020/08/06 04:56

> いいねを押したら、いいねの色や形だけが変わる or いいねの数だけが増える > ⇒getのAjaxを使いましょう 「いいね」するとレコードが登録される仕様なのでGETよりPOSTの方が好ましいと思いますよ。
no1knows

2020/08/06 05:59

あぁ、失礼しました。。。
atage517

2020/08/06 06:46

質問なのですがajaxを使い非同期でいいねをする時にはrenderを使わないといけないのでしょうか? post/show で <% if Like.find_by(user_id: @current_user.id, post_id: @post.id)%> <%= link_to("/likes/#{@post.id}/destroy", method: "post", remote: true) do %> <i class="fas fa-bookmark unclip"></i> <% end %> <% else %> <%= link_to("/likes/#{@post.id}/create", method: "post", remote: true ) do %> <i class="fas fa-bookmark"></i> <% end %> <% end %> このような形を取っている時renderなしで非同期でいいねはできないですかね? ハートマークを押すといいねができて、もう一回押すといいねを消せるという仕様なのですが、調べた方法はどれもハートマークを押すhtmlとそれをcontollerに送るhtmlを作っています。 no1knowsさんのおかげでajaxについてはわかりましたがそれを実行するコードの書き方がまだわかりません
Mugheart

2020/08/06 07:01

renderなしでもできます。renderを使っているのは表示させたいHTMLをパーシャルファイルで作成しておいて、それをjsから埋め込みRubyを使って表示させるのが簡単だからです。render無しでもjsでHTMLを生成してそれを表示させれば同じことができます。
atage517

2020/08/06 07:35

参考サイトを参照して自分でもやってみましたが以下のエラーが出ます、何が原因でしょうか? Missing partial likes/_like with {:locale=>[:ja], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in: * "/Users/hoge/union1/app/views" * "/Users/hoge/union1/vendor/bundle/ruby/2.7.0/gems/actiontext-6.0.3.2/app/views" * "/Users/hoge/union1/vendor/bundle/ruby/2.7.0/gems/actionmailbox-6.0.3.2/app/views" <div id="likes_buttons_<%= @post.id %>"> <i class="fas fa-bookmark"></i> <%= render partial: 'likes/like', locals: { post: @post, likes: @likes} %> ←ここが原因 </div> </div> </div>
Mugheart

2020/08/06 07:46

Missing partial likes/_like とあるように app/views/likes/_like.html.erb が存在していないからじゃないですか?
atage517

2020/08/06 09:19

ありがとうございます。単純なミスでした今の所非同期でいいねはできているようですが、リロードしないと表示されません。 何が原因でしょうか? いいねはできているようですがその画面では見ることができなく、リロードしないといいねが削除されたかいいねされたか確認できません。
atage517

2020/08/06 09:29

ActionView::Template::Error (undefined method `id' for nil:NilClass): 1: $('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>"); app/views/likes/destroy.js.erb:1 エラーにはこうありました。今自分でも原因を探しています
atage517

2020/08/06 10:34

@post = Post.find_by(id: params[:post_id]) で@postのidを取得したらできましたありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問