最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I execute a helper method from inside a JS ERB? - Stack Overflow

programmeradmin3浏览0评论

I have a helper method in my dashboard_helper.rb that looks like this:

  def show_number_of_comments(node)
    if nodements_count == 1
      "#{nodements_count} Comment"
    else
      "#{nodements_count} Comments"
    end
  end

In my regular dashboard#index view, I call it like this:

<h4 class="card-comments-title"><%= show_number_of_comments(node) %></h4>

But I would like to update that rendered element via AJAX whenever a new comment is added, so in my comment#create.js.erb, I would like to reference that helper method but when I try this, it doesn't work:

$('#<%= @card_id %> .card-comments-title').html('<%= show_number_of_comments(@node) %>');

But when I do this, it works:

$('#<%= @card_id %> .card-comments-title').html('<%= @comment_count %> Comments');

The issue with the latter is that it doesn't handle pluralization.

What's the best way to approach this?

Edit 1

When I say it doesn't work, this is what I mean:

NoMethodError at /nodes/5/comments
==================================

> undefined method `show_number_of_comments' for #<#<Class:0x007fbd3715e5b8>:0x007fbd3715d4d8>

app/views/comments/create.js.erb, line 5
----------------------------------------

Also, the @node object is declared in my Comments#Create like this:

  def create
    @node = Node.find(params[:node_id])
    @comment = current_userments.new(comment_params)
    @comment.node = @node
    @card_id = params[:card_id]
    @comment_count = @nodements_count + 1
    current_user.events.create(action: "commented", eventable: @comment)

    binding.pry

    respond_to do |format|
      if @comment.save and @node.save
        format.js
      else
        format.js
      end
    end
  end

When I halt execution via binding.pry as above, and I try to do @node, I get the value I expect:

[1] pry(#<CommentsController>)> @node
=> #<Node id: 5, name: "Reverse Crunches", family_tree_id: 1, user_id: 1, media_id: 5, media_type: "Video", created_at: "2015-07-25 05:49:51", updated_at: "2015-07-25 21:05:34", circa: nil, is_comment: nil, cached_votes_total: 0, cached_votes_score: 0, cached_votes_up: 0, cached_votes_down: 0, cached_weighted_score: 0, cached_weighted_total: 0, cached_weighted_average: 0.0, cached_user_tag_list: nil, cached_num_user_tags: 0, cached_tagged_user_names: [], comments_count: 3>

Edit 2

Sometimes it just fails. It doesn't output any error to either the console or my server log, it just replaces the .card-comments-title with a blank value.

I have a helper method in my dashboard_helper.rb that looks like this:

  def show_number_of_comments(node)
    if node.comments_count == 1
      "#{node.comments_count} Comment"
    else
      "#{node.comments_count} Comments"
    end
  end

In my regular dashboard#index view, I call it like this:

<h4 class="card-comments-title"><%= show_number_of_comments(node) %></h4>

But I would like to update that rendered element via AJAX whenever a new comment is added, so in my comment#create.js.erb, I would like to reference that helper method but when I try this, it doesn't work:

$('#<%= @card_id %> .card-comments-title').html('<%= show_number_of_comments(@node) %>');

But when I do this, it works:

$('#<%= @card_id %> .card-comments-title').html('<%= @comment_count %> Comments');

The issue with the latter is that it doesn't handle pluralization.

What's the best way to approach this?

Edit 1

When I say it doesn't work, this is what I mean:

NoMethodError at /nodes/5/comments
==================================

> undefined method `show_number_of_comments' for #<#<Class:0x007fbd3715e5b8>:0x007fbd3715d4d8>

app/views/comments/create.js.erb, line 5
----------------------------------------

Also, the @node object is declared in my Comments#Create like this:

  def create
    @node = Node.find(params[:node_id])
    @comment = current_user.comments.new(comment_params)
    @comment.node = @node
    @card_id = params[:card_id]
    @comment_count = @node.comments_count + 1
    current_user.events.create(action: "commented", eventable: @comment)

    binding.pry

    respond_to do |format|
      if @comment.save and @node.save
        format.js
      else
        format.js
      end
    end
  end

When I halt execution via binding.pry as above, and I try to do @node, I get the value I expect:

[1] pry(#<CommentsController>)> @node
=> #<Node id: 5, name: "Reverse Crunches", family_tree_id: 1, user_id: 1, media_id: 5, media_type: "Video", created_at: "2015-07-25 05:49:51", updated_at: "2015-07-25 21:05:34", circa: nil, is_comment: nil, cached_votes_total: 0, cached_votes_score: 0, cached_votes_up: 0, cached_votes_down: 0, cached_weighted_score: 0, cached_weighted_total: 0, cached_weighted_average: 0.0, cached_user_tag_list: nil, cached_num_user_tags: 0, cached_tagged_user_names: [], comments_count: 3>

Edit 2

Sometimes it just fails. It doesn't output any error to either the console or my server log, it just replaces the .card-comments-title with a blank value.

Share Improve this question edited Jul 26, 2015 at 1:52 marcamillion asked Jul 15, 2015 at 8:16 marcamillionmarcamillion 33.8k57 gold badges199 silver badges393 bronze badges 3
  • Pure JS approach gives you decoupled logic out of representation, have you tried it yet? – Anatoly Commented Jul 23, 2015 at 16:24
  • What does "it doesn't work" mean, exactly? Do you get an undefined method error? – amiuhle Commented Jul 24, 2015 at 15:14
  • In your HTML view, you call the helper method with node, in your JS you call it with @node. – amiuhle Commented Jul 24, 2015 at 15:16
Add a comment  | 

6 Answers 6

Reset to default 5

So I figured out what I wanted to do in my specific case, i.e. pluralize comment count within my JS ERB, but I haven't figured out how to use a helper_method from within my JS ERB - so this answer doesn't really answer this question.

However, I am documenting this here in case someone else has a similar issue and my solution helps them.

In my JS ERB, all I did was used the Rails method pluralize. I completely forgot about it until I typed up this question and it works like a charm.

Here is the code snippet for my create.js.erb:

$('#<%= @card_id %> .card-comments-title').html('<%= pluralize(@comment_count, "Comment") %>');

Works like a charm, but this still doesn't answer my question about referencing/using helper methods here.

You can also try to avoid using backend if no localisation required:

var comentsNumber = function(num){
  return (num == 0 || num > 1) ? num + " Comments" : num + " Comment"
};
var domObject = $('#<%= @card_id %> .card-comments-title');

Basically you can easily update an object via the AJAX call and trigger content to reload:

var htmlContent = comentsNumber(<%= @comment_count %>);
domObject.html(htmlContent);

A possible better solution to display singular/plural text would be via i18n. You could try something like following:

# config/locales/en.yml

en:
  comments:
    zero: No comments
    one: 1 comment
    other: %{count} comments

Then in your view, you'd use it as:

$('#<%= @card_id %> .card-comments-title').html("<%= t('comments', count: @node.comments_count) %>");

On the problem with helpers not working: Given that you have dashboard_helper.rb in app/helpers/ directory, your helper should work. With the problem you've described where the following line works:

$('#<%= @card_id %> .card-comments-title').html('<%= @comment_count %> Comments');

and the following doesn't:

$('#<%= @card_id %> .card-comments-title').html('<%= show_number_of_comments(@node) %>');

You might find a better answer if you had the output of show_number_of_comments(@node) perhaps using console.log. It is likely that this output needs to be escaped using escape_javascript. So, although not a concrete solution, I'd suggest you to try:

$('#<%= @card_id %> .card-comments-title').html('<%= j show_number_of_comments(@node) %>');

Edit: For Rails 3.1+, the following is only true if

config.action_controller.include_all_helpers = false

Your DashboardHelper is included in the DashboardController. Your .js.erb seems to belong to something like CommentsController.

You will either have to move your helper method to your ApplictionController or include the helper using helper DashboardHelper in the controller you want to use it in.

You could try pluralize:

$('#<%= @card_id %> .card-comments-title').html('<%= pluralize(@comment_count, 'Comment') %>');

It should work in both places.

I missed your own followup.

I'd suggest moving helpers that you need in multiple contexts to the application_helper.rb file. Maybe not the best practice but it would do the job.

Try using j short for escape_javascript.

$('#<%= @card_id %> .card-comments-title').html('<%= j show_number_of_comments(@node) %>');
发布评论

评论列表(0)

  1. 暂无评论