How to render js template from module included in controller?

China☆狼群 提交于 2019-12-22 10:38:16

问题


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

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