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

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

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

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

1617閲覧

[Ruby On Rails]renderやredirect_toを使っていないのにAbstractController::DoubleRenderError

s_diff

総合スコア107

Ruby

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

1グッド

0クリップ

投稿2019/01/10 05:07

編集2019/01/10 06:19

ローカル環境や本番環境では問題ないのですが、staging環境でのみDoubleRenderErrorが出ます。
エラーメッセージの最後にredirect_to(...) and returnとあるのですが、このアクション内にはredirect_toもrenderもないため、別のところに問題があると推測しています。
サーバーが立ち上がらなくなったことがあり、それを復旧した際の処理の何かがおそらく引っかかっているのだと思います。

エラー全文

AbstractController::DoubleRenderError (Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".):

環境

macOS High Sierra(バージョン10.13.6)
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin17]
Rails 4.2.6

##試したこと
以下のようにproduct_controllerのdownloadzipアクションにデバッグを追加してログを確認してみました。

ruby

1# product_controller.rb 2 3def downloadzip 4 @product = Product.find_by(id: params[:id]) 5 download_cnts = DownloadLog.where(user_id: current_user.id).current_month.count 6 plan = current_user.enable_download_plan 7 logger.debug("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 8 return if download_cnts >= plan.download_limit 9 logger.debug("bbbbbbbbbbbbbbbbbbbbbbbbbbbb") 10 file_path = set_zip_url(@product) 11 logger.debug("cccccccccccccccccccccccccccccccc") 12 ActiveRecord::Base.transaction do 13 logger.debug("dddddddddddddddddddddddddddddddd") 14 file_download(file_path, "livesearch") 15 logger.debug("eeeeeeeeeeeeeeeeeeeeeeeeeeeeee") 16 logger.debug(current_user) 17 logger.debug("ffffffffffffffffffffffffffffff") 18 logger.debug(@product) 19 logger.debug("ggggggggggggggggggggggggggggggggg") 20 DownloadLog.create(user_id: current_user.id, product_id: @product.id) 21 logger.debug("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh") 22 end 23 end

staging.logでログを確認すると、
logger.debug("ggggggggggggggggggggggggggggggggg")までは問題ないようですが、logger.debug("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")でのデバッグがなく、DownloadLog.create(user_id: current_user.id, product_id: @product.id)の部分でエラーが起きているようです。

# staging.log D, [2019-01-10T03:13:33.310428 #9193] DEBUG -- : ggggggggggggggggggggggggggggggggg D, [2019-01-10T03:13:33.315289 #9193] DEBUG -- : ESC[1mESC[36mProduct Load (0.3ms)ESC[0m ESC[1mSELECT `products`.* FROM `products` WHERE `products`.`id` = 67 LIMIT 1ESC[0m D, [2019-01-10T03:13:33.316273 #9193] DEBUG -- : ESC[1mESC[35m (0.2ms)ESC[0m SELECT COUNT(*) FROM `download_logs` WHERE `download_logs`.`product_id` = 67 D, [2019-01-10T03:13:35.683743 #9193] DEBUG -- : ESC[1mESC[36m (0.1ms)ESC[0m ESC[1mROLLBACKESC[0m E, [2019-01-10T03:13:35.684035 #9193] ERROR -- : Rendering 500 with exception: undefined method `[]' for nil:NilClass I, [2019-01-10T03:13:35.947113 #9193] INFO -- : Completed 500 Internal Server Error in 3226ms (ActiveRecord: 8.6ms) F, [2019-01-10T03:13:36.198009 #9193] FATAL -- : AbstractController::DoubleRenderError (Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".): app/controllers/application_controller.rb:51:in `block (2 levels) in handle_500' app/controllers/application_controller.rb:49:in `handle_500'

Rendering 500 with exception: undefined method `[]' for nil:NilClassとありますが、[]を記述していないので、なぜこのエラーができているのかわかりません。model/download_log.rbにもapplication_controller.rbのhandle500にも記述はありませんでした。

ruby

1# model/download_log.rb 2 3class DownloadLog < ActiveRecord::Base 4 belongs_to :user, foreign_key: 'user_id' 5 belongs_to :product, foreign_key: 'product_id' 6 7 scope :current_month, -> { where(created_at: Time.current.beginning_of_month..Time.current.end_of_month) } 8 9 before_save :set_dl_cnt_to_product 10 11 def set_dl_cnt_to_product 12 self.product.update(dl_cnt: DownloadLog.where(product_id: self.product.id).count + 1) 13 end 14end 15

ruby

1# application_controller.rb 2 3class ApplicationController < ActionController::Base 4 protect_from_forgery with: :exception 5 rescue_from Exception, with: :handle_500 unless Rails.env.development? 6 7 def handle_500(exception = nil) 8 logger.error "Rendering 500 with exception: #{exception.message}" if exception 9 ExceptionNotifier.notify_exception(exception, env: request.env, data: {message: "error"}) 10 respond_to do |format| 11 format.html { 12 return render template: 'errors/error_500', status: 500, layout: false, content_type: 'text/html' 13 } 14 format.all { 15 return head :internal_server_error 16 } 17 end 18 end 19end

また、application_controller.rbのhandle_505内の

ruby

1return render template: 'errors/error_500', status: 500, layout: false, content_type:

の一行を

ruby

1render template: 'errors/error_500', status: 500, layout: false, content_type: and return

と変えてみましたがエラーメッセージに変化はありませんでした。

実現したいこと

staging環境でのみAbstractController::DoubleRenderErrorが起こる原因を究明したいです。
ご教示いただけることがあれば、何卒よろしくお願いいたします。

退会済みユーザー👍を押しています

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

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

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

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

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

macaron_xxx

2019/01/10 09:34

こういうのって、意外と再起動したら直った的なこともありますが、再起動なんか試したりしましたか?
s_diff

2019/01/15 00:34 編集

コメント有難うございます。 再起動はcapistranoでデプロイ時にするようになっていて何度も試しています。
guest

回答1

0

ベストアンサー

file_download(file_path, "livesearch")

という部分から推測すると、ここの時点でHTTPのレスポンスを返してしまっているのではないかと思います。
そうだったとすると、この時点でサーバ側の処理は完了していなければならないはずです。

この行を一番最後、トランザクションのブロックよりも後に持ってくると動作しますか?

投稿2019/01/12 10:18

takahashim

総合スコア1877

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

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

s_diff

2019/01/15 03:01

回答有難うございます! 返信が遅れて申し訳ありません。 この行をトランザクションのブロックよりも後に持ってくると、動作しました。 そして DownloadLog.create(user_id: current_user.id, product_id: @product.id) が行われてないようでした。 調べてみると、model/download_log.rbで良くない書き方のコードがあったため、それを削除すると問題なく動きました。該当のコードは以下です。 before_save :set_dl_cnt_to_product def set_dl_cnt_to_product self.product.update(dl_cnt: DownloadLog.where(product_id: self.product.id).count + 1) end 問題になる箇所をご指摘してくださり、本当に有難うございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問