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

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

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

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

Ruby

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

Ruby on Rails

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

解決済

【Ruby on Rails】フォロー機能の非同期が一部反映されない。

is02
is02

総合スコア17

Ruby on Rails 5

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

Ruby

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

Ruby on Rails

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

2回答

0評価

0クリップ

1611閲覧

投稿2020/02/07 03:09

編集2020/02/09 14:29

前提・実現したいこと

フォロー機能の非同期が一部出来ない。
イメージ説明

上記の画像のように、画像を投稿した最新のものには、非同期フォローが出来ているんですけど、
過去に投稿したものには非同期で反映されません。(リロードすると反映されます)

発生している問題・エラーメッセージ

検証ツールのconsoleにて、非同期が出来ていない部分を確認してみると、
500 (Internal Server Error)というエラーが出ていました。

該当のソースコード

####モデル
user.rb

class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :post_images, dependent: :destroy has_many :favorites, dependent: :destroy has_many :fav_post_images, through: :favorites, source: :post_image has_many :cosplay_favorites, dependent: :destroy has_many :cosplay_fav_post_images, through: :favorites, source: :post_image has_many :post_comments, dependent: :destroy has_many :relationships has_many :followings, through: :relationships, source: :follow has_many :reverse_of_relationships, class_name: 'Relationship', foreign_key: 'follow_id' has_many :followers, through: :reverse_of_relationships, source: :user # 2~8文字以内で名前が入っているかの確認 validates :name, presence: true, length: { in: 2..8 }, uniqueness: true # 自己紹介 100文字以内 validates :introduction, length: { maximum: 100 } # 可能なコスプレ 100文字以内 validates :like_cos, length: { maximum: 100 } # refile定義 attachment :profile_image # フォロー機能のメソッド def follow(other_user) unless self == other_user # フォローしようとしている人が自分自身ではないか # フォローしようとしている人が自分以外ならフォローする self.relationships.find_or_create_by(follow_id: other_user.id) end end def unfollow(other_user) relationship = self.relationships.find_by(follow_id: other_user.id) relationship.destroy if relationship # フォローしていたらアンフォローする end def following?(other_user) self.followings.include?(other_user) # other_userが含まれていたらtrueを返す end end

relationship.rb

class Relationship < ApplicationRecord belongs_to :user # userモデルを参照する belongs_to :follow, class_name: 'User' validates :user_id, presence: true validates :follow_id, presence: true end

post_image.rb

class PostImage < ApplicationRecord belongs_to :user has_many :favorites, dependent: :destroy has_many :fav_users, through: :favorites, source: :user has_many :cosplay_favorites, dependent: :destroy has_many :cosplay_fav_users, through: :cosplay_favorites, source: :user has_many :post_comments, dependent: :destroy # refile定義 attachment :real_image attachment :cosplay_image validates :real_image, presence: true validates :cosplay_image, presence: true # 投稿を降順に並び替えし、最新のものを上にくるようにする default_scope -> { order(created_at: :asc) } end

####コントローラー
users_controller.rb

class UsersController < ApplicationController def show @user = User.find(params[:id]) @post_images = @user.post_images end def edit @user = User.find(params[:id]) end def update @user = User.find(params[:id]) if @user.update(user_params) redirect_to user_path(@user.id) else render 'edit' end end def following @user = User.find(params[:id]) @users = @user.followings render 'show_follow' end def followers @user = User.find(params[:id]) @users = @user.followers render 'show_follower' end private def user_params params.require(:user).permit(:name, :profile_image, :introduction, :like_cos) end end

relationships_controller.rb

class RelationshipsController < ApplicationController before_action :set_user def create following = current_user.follow(@user) following.save respond_to do |format| format.html { redirect_to @user } format.js end end def destroy following = current_user.unfollow(@user) following.destroy respond_to do |format| format.html { redirect_to @user } format.js end end private def set_user @user = User.find(params[:follow_id]) end end

post_images_controller.rb

class PostImagesController < ApplicationController def new @post_image = PostImage.new end # 投稿データの保存 def create @post_image = PostImage.new(post_image_params) @post_image.user_id = current_user.id if @post_image.save redirect_to post_images_path else render 'new' end end def index @post_images = PostImage.page(params[:page]).reverse_order end def show @post_image = PostImage.find(params[:id]) @post_comment = PostComment.new end def destroy @post_image = PostImage.find(params[:id]) @post_image.destroy redirect_to post_images_path end private # 投稿データのストロングパラメータ def post_image_params params.require(:post_image).permit(:real_image_name, :cosplay_image_name, :real_image, :cosplay_image, :caption, :favorites_count) end end

####ビュー
relationships/_follow_button.rb

<% unless current_user == user %> <div id="follow_form"> <% if current_user.following?(user) %> <%= form_for(current_user.relationships.find_by(follow_id: user.id), html: { method: :delete }, remote: true) do |f| %> <%= hidden_field_tag :follow_id, user.id %> <%= f.submit 'フォロー中' %> <% end %> <% else %> <%= form_for(current_user.relationships.build, remote: true) do |f| %> <%= hidden_field_tag :follow_id, user.id %> <%= f.submit 'フォローする' %> <% end %> <% end %> </div> <% end %>

create.js.erb

$("<%= '#follow_form' %>").html('<%= escape_javascript(render("relationships/follow_button", user: @user )) %>');

destroy.js.erb

$("<%= '#follow_form' %>").html('<%= escape_javascript(render("relationships/follow_button", user: @user )) %>');

post_images/index.html.erb

<% @post_images.each do |post_image| %> <%= render 'relationships/follow_button', user: post_image.user %> <% end %>

補足情報(FW/ツールのバージョンなど)

ruby 2.5.7p206
Rails 5.2.4.1

###追記

####_follow_button.html.erb

<% unless current_user == user %> <div id="follow_form_<%= user.id %>"> <% if current_user.following?(user) %> <%= form_for(current_user.relationships.find_by(follow_id: user.id), html: { method: :delete }, remote: true) do |f| %> <%= hidden_field_tag :follow_id, user.id %> <%= f.submit 'フォロー中' %> <% end %> <% else %> <%= form_for(current_user.relationships.build, remote: true) do |f| %> <%= hidden_field_tag :follow_id, user.id %> <%= f.submit 'フォローする' %> <% end %> <% end %> </div> <% end %>

####create.js.erb, destroy.js.erb

$("<%= @userid %>").html('<%= escape_javascript(render("relationships/follow_button", user: @user )) %>');

####relationships_controller.rb

class RelationshipsController < ApplicationController before_action :set_user def create following = current_user.follow(@user) following.save respond_to do |format| format.html { redirect_to @user } format.js end end def destroy following = current_user.unfollow(@user) following.destroy if following respond_to do |format| format.html { redirect_to @user } format.js end end private def set_user @user = User.find(params[:follow_id]) @userid = "#follow_form_#{@user.id}" end end

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

winterboum
winterboum

2020/02/07 09:14

500エラーが出たところのlogを載せてください
is02
is02

2020/02/07 09:18

コメントありがとうございます。載せました、よろしくお願いします。
winterboum
winterboum

2020/02/07 09:19

それではなく、logを見たいです
is02
is02

2020/02/07 09:23

すみません、ターミナル上のログ載せました。
is02
is02

2020/02/07 09:25

非同期が出来ている箇所のログに赤文字が出ていたので、念のために非同期が出来ている箇所と出来ていない箇所のログを載せました。
is02
is02

2020/02/07 09:29

また、非同期が出来ていない箇所のフォローボタンを押すと、非同期が出来ている箇所が切り替わります。
winterboum
winterboum

2020/02/07 10:31

textで載せてほしいなぁ。 読みにくいしコピペできないんで回答への引用も面倒
winterboum
winterboum

2020/02/07 10:32

「500 (Internal Server Error)というエラーが出ていました。」というのが見当たりません
is02
is02

2020/02/07 14:23 編集

申し訳ありません。 ログ中にCannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255という文言があり、エラーのような気がしたので、config/application.rb内に「config.web_console.whitelisted_ips = '10.0.2.2'」というものを追記しました。(それ以降でなくなりました。) また、検証ツールでserver error 500の部分を見ていると、 NoMethodError in RelationshipsController#destroy undefined method `destroy' for nil:NilClass Extracted source (around line #15): #13 def destroy #14 following = current_user.unfollow(@user) *15 following.destroy #16 respond_to do |format| #17 format.html { redirect_to @user } #18 format.js Extracted source (around line #6): #4 module BasicImplicitRender # :nodoc: #5 def send_action(method, *args) *6 super.tap { default_render unless performed? } #7 end #8 #9 def default_render(*args) Extracted source (around line #194): #192 # which is *not* necessarily the same as the action name. #193 def process_action(method_name, *args) *194 send_action(method_name, *args) #195 end #196 #197 # Actually call the method associated with the action. Override というエラーが出ているのが分かりました。 following.destroyのdestroyの中身が定義されていないということで、確認しているのですが、どう直せばいいか分かりません。よろしくお願いします。
is02
is02

2020/02/07 14:28

【非同期出来ている箇所のログ】 「フォローを外すときのログ」 Started DELETE "/relationships/43" for 10.0.2.2 at 2020-02-07 14:27:10 +0000 Processing by RelationshipsController#destroy as JS Parameters: {"utf8"=>"?", "follow_id"=>"5", "commit"=>"フォロー中", "id"=>"43"} User Load (5.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 4], ["LIMIT", 1]] ? /var/lib/gems/2.5.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98 User Load (5.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] ? app/controllers/relationships_controller.rb:25 Relationship Load (6.7ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."user_id" = ? AND "relationships"."follow_id" = ? LIMIT ? [["user_id", 4], ["follow_id", 5], ["LIMIT", 1]] ? app/models/user.rb:37 (0.3ms) begin transaction ? app/models/user.rb:38 Relationship Destroy (30.3ms) DELETE FROM "relationships" WHERE "relationships"."id" = ? [["id", 43]] ? app/models/user.rb:38 (30.9ms) commit transaction ? app/models/user.rb:38 (0.2ms) begin transaction ? app/controllers/relationships_controller.rb:15 (0.2ms) commit transaction ? app/controllers/relationships_controller.rb:15 Rendering relationships/destroy.js.erb User Exists (5.4ms) SELECT 1 AS one FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follow_id" WHERE "relationships"."user_id" = ? AND "users"."id" = ? LIMIT ? [["user_id", 4], ["id", 5], ["LIMIT", 1]] ? app/models/user.rb:42 Rendered relationships/_follow_button.html.erb (19.3ms) Rendered relationships/destroy.js.erb (190.5ms) Completed 200 OK in 960ms (Views: 659.6ms | ActiveRecord: 84.8ms) 「フォローするときのログ」 Started POST "/relationships" for 10.0.2.2 at 2020-02-07 14:28:18 +0000 (6.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC ? /var/lib/gems/2.5.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98 Processing by RelationshipsController#create as JS Parameters: {"utf8"=>"?", "follow_id"=>"5", "commit"=>"フォローする"} User Load (6.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 4], ["LIMIT", 1]] ? /var/lib/gems/2.5.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98 User Load (3.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] ? app/controllers/relationships_controller.rb:25 Relationship Load (4.1ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."user_id" = ? AND "relationships"."follow_id" = ? LIMIT ? [["user_id", 4], ["follow_id", 5], ["LIMIT", 1]] ? app/models/user.rb:32 (0.1ms) begin transaction ? app/models/user.rb:32 User Load (4.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] ? app/models/user.rb:32 Relationship Create (18.6ms) INSERT INTO "relationships" ("user_id", "follow_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 4], ["follow_id", 5], ["created_at", "2020-02-07 14:28:18.906367"], ["updated_at", "2020-02-07 14:28:18.906367"]] ? app/models/user.rb:32 (18.5ms) commit transaction ? app/models/user.rb:32 (0.1ms) begin transaction ? app/controllers/relationships_controller.rb:6 (0.1ms) commit transaction ? app/controllers/relationships_controller.rb:6 Rendering relationships/create.js.erb User Exists (3.7ms) SELECT 1 AS one FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follow_id" WHERE "relationships"."user_id" = ? AND "users"."id" = ? LIMIT ? [["user_id", 4], ["id", 5], ["LIMIT", 1]] ? app/models/user.rb:42 Relationship Load (4.6ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."user_id" = ? AND "relationships"."follow_id" = ? LIMIT ? [["user_id", 4], ["follow_id", 5], ["LIMIT", 1]] ? app/views/relationships/_follow_button.html.erb:4 Rendered relationships/_follow_button.html.erb (34.0ms) Rendered relationships/create.js.erb (145.7ms) Completed 200 OK in 874ms (Views: 450.4ms | ActiveRecord: 107.9ms)
is02
is02

2020/02/07 14:30

【非同期出来ていない箇所のログ】 「フォローするときのログ」 Started POST "/relationships" for 10.0.2.2 at 2020-02-07 14:29:08 +0000 (6.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC ? /var/lib/gems/2.5.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98 Processing by RelationshipsController#create as JS Parameters: {"utf8"=>"?", "follow_id"=>"5", "commit"=>"フォローする"} User Load (3.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 4], ["LIMIT", 1]] ? /var/lib/gems/2.5.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98 User Load (3.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] ? app/controllers/relationships_controller.rb:25 Relationship Load (5.3ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."user_id" = ? AND "relationships"."follow_id" = ? LIMIT ? [["user_id", 4], ["follow_id", 5], ["LIMIT", 1]] ? app/models/user.rb:32 (0.1ms) begin transaction ? app/controllers/relationships_controller.rb:6 User Load (3.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] ? app/controllers/relationships_controller.rb:6 (0.2ms) commit transaction ? app/controllers/relationships_controller.rb:6 Rendering relationships/create.js.erb User Exists (2.8ms) SELECT 1 AS one FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follow_id" WHERE "relationships"."user_id" = ? AND "users"."id" = ? LIMIT ? [["user_id", 4], ["id", 5], ["LIMIT", 1]] ? app/models/user.rb:42 CACHE Relationship Load (0.0ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."user_id" = ? AND "relationships"."follow_id" = ? LIMIT ? [["user_id", 4], ["follow_id", 5], ["LIMIT", 1]] ? app/views/relationships/_follow_button.html.erb:4 Rendered relationships/_follow_button.html.erb (23.4ms) Rendered relationships/create.js.erb (91.1ms) Completed 200 OK in 551ms (Views: 267.8ms | ActiveRecord: 50.8ms) 非同期出来ていない箇所は、フォロー外すときのログが出ませんでした。
winterboum
winterboum

2020/02/07 21:07

14 following = current_user.unfollow(@user) 15 following.destroy 14で該当するunfollowがなかったのでnilが入りそれで15となりました。 following.destroy if follwing とでもしてください。 そもそもdestroyすべき対象が居ないの削除ボタンが機能するのがおかしいですが

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Ruby on Rails 5

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

Ruby

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

Ruby on Rails

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