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'
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 :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.