Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I execute a helper method from inside a JS ERB?

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.

like image 617
marcamillion Avatar asked Jul 15 '15 08:07

marcamillion


People also ask

How do you use the helper method in Ruby on Rails?

A helper is a method that is (mostly) used in your Rails views to share reusable code. Rails comes with a set of built-in helper methods. One of these built-in helpers is time_ago_in_words . This method is helpful whenever you want to display time in this specific format.

What is a helper method in JavaScript?

Helper functions are JavaScript functions that you can call from your template. Ember's template syntax limits what you can express to keep the structure of your application clear at a glance. When you need to compute something using JavaScript, you can use helper functions.

Can we use helper method in controller rails?

In Rails 5, by using the new instance level helpers method in the controller, we can access helper methods in controllers.


2 Answers

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.

like image 65
marcamillion Avatar answered Oct 11 '22 21:10

marcamillion


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);
like image 28
Anatoly Avatar answered Oct 11 '22 21:10

Anatoly