Search code examples
jqueryruby-on-railsajaxxmlhttprequesthttp-status-code-500

Rails ajax call not converting erb elements to html


There's probably a much better title for this, but I don't what the technical terms would be

Anyway, I'm performing an ajax call that appends a link to a div. The link contains erb code such as

#{post.comments.count}

$('#comments_<%= @post.id %>').append("<%= escape_javascript (link_to 'view all #{post.comments.count} comments', post_comments_path(@post), remote: true, class: 'more-comments', id: 'more_comments_#{post.id}', data: {post_id: @post.id, type: 'html', value: '#{post.comments.count}' }) %>"); }`

The link ends up looking like this:

<br/><br>
view all #{post.comments.count} comments
<br>
<br>

This is what the link looks like when inspecting it:

<a class="more-comments" id="more_comments_#{post.id}" data-post-id="4" data-type="html" data-value="#{post.comments.count}" data-remote="true" href="/posts/4/comments">view all #{post.comments.count} comments</a>

When I try using <%= %> in the code, I end up getting 500 errors. With other AJAX links using <%= %> I'm not being thrown these 500 errors.

For example:

This works:

$('#more_comments_<%= @post.id %>').html("view all <%= @post.comments.count %> comments");

This doesn't:

$('#comments_<%= @post.id %>').append("<%= escape_javascript (link_to 'view all <%= @post.comments.count %> comments', post_comments_path(@post), remote: true, class: 'more-comments', id: 'more_comments_<%= @post.id %>', data: {post_id: @post.id, type: 'html', value: <%= @post.comments.count %> }) %>");

This throws this error:

POST http://localhost:3000/posts/4/comments 500 (Internal Server Error)

I tried circumventing this by 'splicing' the link together with JS held variables:

$('#comments_' + Append.id).append("<%= link_to 'view all " + Append.comment_count + " comments', post_comments_path(" + Append.id + "), remote: true, class: 'more-comments', id: 'more_comments_" + Append.id + "', data: {post_id: " + Append.id + ", type: 'html', value: " + Append.comment_count + " } %>");

And I'm still receiving the 500 error.

The comments controller looks like such,

def index
        @post = Post.find(params[:post_id])
        @comments = @post.comments.all.order("created_at ASC")
        respond_to do |format|
            format.html { render layout: !request.xhr? }
            format.js
        end 
    end
end

I can't find this exact issue on stackoverflow, I'm probably just not googling (TIL googling is a word) the right key words. Lots of E-love for those who made it this far


Solution

  • Seems like you're trying to use ERB tags (<%= %>) where you should be using standard Ruby string interpolation (#{ }).

    ERB tags can only be used in certain places, i.e. .erb files.

    Furthermore, ERB tags cannot be nested. So in your example,

    $('#comments_<%= @post.id %>').append("<%= escape_javascript (link_to 'view all <%= @post.comments.count %> comments', post_comments_path(@post), remote: true, class: 'more-comments', id: 'more_comments_<%= @post.id %>', data: {post_id: @post.id, type: 'html', value: <%= @post.comments.count %> }) %>");
    

    the problem is the ERB tags inside the escape_javascript method, which should be replaced with standard Ruby string interpolation.

    FYI, saying that you have a 500 error is not useful unless you show the actual error. Since 500 is the 'generic' error, it can result from a practically infinite set of circumstances.