问题
I have an action in a controller concern, which gets included in a controller. This action does not render a js.erb file as specified under a respond_to block. How do I properly get an action in a controller concern to successfully render a js.erb file (or any view, for that matter)? Is it a problem with my routes?
The link for the module action
= link_to image_tag("upvote.png"),
send("vote_socionics_#{votable_name}_path", votable, vote_type: "#{s.type_two_im_raw}"),
id: "vote-#{s.type_two_im_raw}",
method: :post,
remote: true
** The link for the controller action**
= link_to "whatever", characters_whatever_path, remote: true
controllers/characters_controller.rb
class CharactersController < ApplicationController
include SocionicsVotesConcern
def an_action
respond_to do |format|
format.js { render 'shared/vote_socionics' } # This renders/executes the file
end
end
controllers/concerns/socionics_votes_concern.rb
module SocionicsVotesConcern
extend ActiveSupport::Concern
def vote_socionics
respond_to do |format|
format.js { render 'shared/vote_socionics' } # This DOES NOT render/execute the file. Why?
end
end
end
views/shared/whatever.js.erb
# js code that executes
routes.rb
concern :socionics_votes do
member do
post 'vote_socionics'
end
end
resources :universes
resources :characters, concerns: :socionics_votes
resources :celebrities, concerns: :socionics_votes
resources :users, concerns: :socionics_votes
回答1:
module SocionicsVotesConcern
extend ActiveSupport::Concern
included do
def vote_socionics
respond_to do |format|
format.js { render 'shared/vote_socionics' }
end
end
end
end
Wrap any actions/methods you define in the concern in an included do
block. This way, anything in the block will be considered as if it was directly written in the includer object (i.e. the controller you're mixing this into)
With this solution, there are no loose ends, no idiosyncracies, no deviations from rails patterns. You will be able to use respond_to
blocks, and won't have to deal with weird stuff.
回答2:
I don't think this is Rails compatible man.
- A controller action renders a view or redirects;
- A module has methods. Methods executes code;
So just including the methods from a module named as a controller is not gonna work. What you really need to do is to call an action from controller A to controller B.So SocionicsVotesController would turn into a real controller class and you would use the redirect_to rails method.
You would have to specify the controller and action you're redirecting to, like:
redirect_to :controller => 'socionics', :action => 'index'
Or just:
redirect_to socionics_url
Which will send a HTTP 302 FOUND by default.
EDITED:
If you want to reuse the way your controller actions respond, while using rails 4 concerns, try this:
class CharactersController < ApplicationController
include SocionicsVotesControllerConcerns # not actually a controller, just a module.
def an_action
respond
end
module SocionicsVoteControllerConcerns
extend ActiveSupport::Concern
def respond
respond_to do |format|
format.html { render 'whatever' }
format.json { head :no_content }
end
end
end
I only got it to work when changing format.js to format.html, maybe because of this.
来源:https://stackoverflow.com/questions/24772898/how-to-render-js-template-from-module-included-in-controller