Ruby on Rails - 二重レンダリングエラー - リダイレクトとリターン
概要
エラー: AbstractController::DoubleRenderError (このアクションでは、レンダーおよび/またはリダイレクトが複数回呼び出されています。レンダーまたはリダイレクトを呼び出せるのはアクションごとに 1 回だけであることに注意してください。また、リダイレクトもレンダーもアクションの実行を終了しないことに注意してください)したがって、リダイレクト後にアクションを終了したい場合は、「redirect_to(…) and return」のようなことを行う必要があります。)
更新時に、モデルは template.exists? をチェックし、true の場合、レポートをダウンロードし、親オブジェクトにリダイレクトします。それ以外の場合は、リダイレクトするだけです。
「if」ステートメントの接線側で「and return」を使用しているのですが、なぜ期待どおりに機能しないのですか?
def update
template = resource.check_changes(params[:well_master])
paramString = resource.to_json
update! do |format|
if resource.errors.present?
return render :edit
else
if template != ''
generateWellLetter(template, 'Rpt_Farm_Name', paramString)
else
rec = resource.PERMIT
format.html { redirect_to admin_well_master_path(rec) }
end
end
end
end
def generateWellLetter(template, letterName, params)
@URL = "#{ENV["API_HOST"]}/api/Document/Generate/#{template}"
response = HTTParty.post(@URL,
:body => params,
:headers => { "Content-Type" => "application/json" })
Zip::InputStream.open(StringIO.new(response)) do |io|
while entry = io.get_next_entry
report = io.read
send_data report, :filename => letterName + '.docx', :type => 'docx'
end
end
respond_to do |format|
rec = resource.PERMIT
format.html { redirect_to admin_well_master_path(rec) } and return
end
end
解決策
レンダリングの回数が多すぎるため、レンダリング呼び出しをまとめて保持することをお勧めします。
# send_data is like render, you can only call it once
while entry = io.get_next_entry
report = io.read
send_data report, filename: letterName + ".docx", type: "docx"
end
# can't send_data and also render
#
# can't use respond_to and respond_with (from inherited_resources -> responders)
# that's what `update!` method is for
#
# returning inside of the respond_to block means
# `redirect_to admin_well_master_path(rec)` never runs
respond_to do |format|
rec = resource.PERMIT
format.html { redirect_to admin_well_master_path(rec) } and return
end
継承されたリソースを使用している場合は、おそらくそれを使用する必要があります。そうでない場合は役に立たないため、独自のロジックでresponse_toブロックを使用する必要があります。
def update
template = resource.check_changes(params[:well_master])
update! do |success, failure|
# failure - already renders :edit so it's not needed
success.html do
if template.present?
generate_well_letter(template, resource.to_json) do |report|
send_data report, filename: "Rpt_Farm_Name.docx", type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
end
else
redirect_to admin_well_master_path(resource.PERMIT)
end
end
end
end
def generate_well_letter(template, json)
url = "#{ENV["API_HOST"]}/api/Document/Generate/#{template}"
response = HTTParty.post(url, body: json, headers: {"Content-Type" => "application/json"})
# either you're sending the whole zip file or just one file from the zip file
Zip::InputStream.open(response) do |io|
entry = io.get_next_entry
report = entry.get_input_stream.read
yield report
end
end
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/activeadmin/inherited_resources#overwriting-actions