Rendering a view of controller action from around_action callback

风流意气都作罢 提交于 2019-12-07 10:27:01

问题


I'm rendering a js.erb partial which enables ajax functionality to like/dislike a restaurant dish. I recently came across the around_action callback and figured yield would help perform the controller action first and render the template second. Unfortunately I'm getting a 500 (Internal Server Error) due to the respond_to never getting called.

The respond_to method works if I place it inside the controller action but not inside the callback. What am I doing wrong?

class DishesController < ApplicationController
  before_action :set_dish_and_restaurant
  around_action :render_vote_partial

  def like
    @dish.liked_by current_user
  end

  ...

  private
    def set_dish_and_restaurant
      @dish = Dish.find(params[:id])
    end

    def render_vote_partial
      yield
      respond_to { |format| format.js { render "vote.js.erb" } }
    end
end

Console Error

ActionView::MissingTemplate (Missing template dishes/like, application/like with {:locale=>[:en], :formats=>[:js, "application/ecmascript", "application/x-ecmascript", :html, :text, :js, :css, :ics, :csv, :vcf, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
  * "/app/views"
  * "/Library/Ruby/Gems/2.0.0/gems/devise-3.5.1/app/views"
):
  app/controllers/dishes_controller.rb:29:in `render_vote_partial'

回答1:


Okay so with your stack trace it is pretty clear what is happening. You have to understand the default rails behavior of convention over configuration.

As soon as you call yield, your controller action gets called. Now all controller actions by default look to render views with the same name as action, once the actions are done executing.

So calling render_to after yield doesn't make any sense, as controller action you yielded to has already called its render :)

In any case what you are trying to do is a bad design pattern, rendering views should be left to actions

Update

Theoretically speaking : As you wish to keep things DRY you could render the same view after each action by creating a common method calling it after every action. However, think about it, your render will have one line, and calling that same method will need one line too :) so where's the DRY.

In short, DRY should not be over done at the cost of simplicity. In my opinion KISS trumps DRY :)



来源:https://stackoverflow.com/questions/31858077/rendering-a-view-of-controller-action-from-around-action-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!