Is that possible to call method that uses "content_tag" from controller in Rails 3?
In my Rails 3 application I use Ajax to get a formatted HTML:
$.get("/my/load_page?page=5", function(data) {
alert(data);
});
class MyController < ApplicationController
def load_page
render :js => get_page(params[:page].to_i)
end
end
get_page
uses the content_tag
method and should be available also in app/views/my/index.html.erb
.
Since get_page
u开发者_C百科ses many other methods, I encapsulated all the functionality in:
# lib/page_renderer.rb
module PageRenderer
...
def get_page
...
end
...
end
and included it like that:
# config/environment.rb
require 'page_renderer'
# app/controllers/my_controller.rb
class MyController < ApplicationController
include PageRenderer
helper_method :get_page
end
But, since the content_tag
method isn't available in app/controllers/my_controller.rb
, I got the following error:
undefined method `content_tag' for #<LoungeController:0x21486f0>
So, I tried to add:
module PageRenderer
include ActionView::Helpers::TagHelper
...
end
but then I got:
undefined method `output_buffer=' for #<LoungeController:0x21bded0>
What am I doing wrong ?
How would you solve this ?
To answer the proposed question, ActionView::Context defines the output_buffer method, to resolve the error simply include the relevant module:
module PageRenderer
include ActionView::Helpers::TagHelper
include ActionView::Context
...
end
Helpers are really view code and aren't supposed to be used in controllers, which explains why it's so hard to make it happen.
Another (IMHO, better) way to do this would be to build a view or partial with the HTML that you want wrapped around the params[:page].to_i. Then, in your controller, you can use render_to_string to populate :js in the main render at the end of the load_page method. Then you can get rid of all that other stuff and it'll be quite a bit cleaner.
Incidentally, helper_method does the opposite of what you're trying to do - it makes a controller method available in the views.
If you don't want to include all of the cruft from those two included modules, another option is to call content_tag
via ActionController::Base.helpers
. Here's some code I recently used to achieve this, also utilizing safe_join
:
helpers = ActionController::Base.helpers
code_reactions = user_code_reactions.group_by(&:code_reaction).inject([]) do |arr, (code_reaction, code_reactions_array)|
arr << helpers.content_tag(:div, nil, class: "code_reaction_container") do
helpers.safe_join([
helpers.content_tag(:i, nil, class: "#{ code_reaction.fa_style } fa-#{ code_reaction.fa_icon }"),
helpers.content_tag(:div, "Hello", class: "default_reaction_description"),
])
end
end
精彩评论