Issues with Rails comments not displaying properly when using ajax requests

I've implemented ajax comments in my rails app and while I can see the comments are being processed in the console, they're not displaying/rendering on the page. My javascript appears to be functioning correctly, but I'm unsure where the issue lies

User Profile Page

<div class="comments">
  <h2>Comments</h2>
  <%= render :partial => 'comments/form', :locals => { :comment => @new_comment } %>
  <%= render :partial => 'comments/comment', :collection => @comments, :as => :comment %>
</div>

Comment Partial

<div class="comment"  id="comment-<%= comment.id %>">
   <hr>

    <%= link_to "×", comment_path(comment), :method => :delete, :remote => true, :confirm => "Are you sure you want to remove this comment?", :disable_with => "×", :class => 'close' %>
    <h4>
      <%= comment.user.username %>
      <small>
        <%= comment.updated_at %>
      </small>
    </h4>
  <p>
    <%= comment.body %>
  </p>
</div>

Comment Form Partial

<div class="comment-form">
  <%= simple_form_for comment,:url => comments_path,  :remote => true do |f| %>
    <%= f.input :body, :input_html => { :rows => "2" }, :label => false %>
    <%= f.input :commentable_id, :as => :hidden, :value => comment.commentable_id %>
    <%= f.input :commentable_type, :as => :hidden, :value => comment.commentable_type %>
    <%= f.button :submit, :class => "", :disable_with => "Submitting…" %>
  <% end %>
</div>

Comments Controller

def create 
  @comment_hash = params[:comment]
  @obj = @comment_hash[:commentable_type].constantize.find(@comment_hash[:commentable_id])
  # Not implemented: check to see whether the user has permission to create a comment on this object
  @comment = Comment.build_from(@obj, current_user, @comment_hash[:body])
  if @comment.save
    render :partial => "comments/comment", :locals => { :comment => @comment }, :layout => false, :status => :created
  else
    render :js => "alert('error saving comment');"
  end

 def destroy
    @comment = Comment.find(params[:id])
    if @comment.destroy
      render :json => @comment, :status => :ok
    else
      render :js => "alert('error deleting comment');"
    end
  end

comments.js.coffee

jQuery ->
  # create a comment
  $(".comment-form")
    .on "ajax:beforeSend", (evt, xhr, settings) ->
      $(this).find('textarea')
        .addClass('uneditable-input')
        .attr('disabled', 'disabled');
    .on "ajax:success", (evt, data, status, xhr) ->
      $(this).find('textarea')
        .removeClass('uneditable-input')
        .removeAttr('disabled', 'disabled')
        .val('');
      $(xhr.responseText).hide().insertAfter($(this)).show('slow')

      #delete/destroy a comment
      $(document)
    .on "ajax:beforeSend", ".comment", ->
      $(this).fadeTo('fast', 0.5)
    .on "ajax:success", ".comment", ->
      $(this).hide('fast')
    .on "ajax:error", ".comment", ->
      $(this).fadeTo('fast', 1)

Users Controller

def show
  @user = User.find(params[:id])

  # Another way to find by username: 
  #@user= User.find_by_username(params[:username])
  @comments = @user.comment_threads.order('created_at desc')
  @new_comment = Comment.build_from(@user, current_user, "")
end   

UPDATE

Comment Model

 class Comment < ActiveRecord::Base
  acts_as_nested_set :scope => [:commentable_id, :commentable_type]

  validates :body, :presence => true
  validates :user, :presence => true

  # NOTE: install the acts_as_votable plugin if you
  # want user to vote on the quality of comments.
  #acts_as_votable

  belongs_to :commentable, :polymorphic => true

  # NOTE: Comments belong to a user
  belongs_to :user

  # Helper class method that allows you to build a comment
  # by passing a commentable object, a user_id, and comment text
  # example in readme
  def self.build_from(obj, user_id, comment)
    new \
      :commentable => obj,
      :body        => comment,
      :user_id     => user_id
  end

  #helper method to check if a comment has children
  def has_children?
    self.children.any?
  end

  # Helper class method to lookup all comments assigned
  # to all commentable types for a given user.
  scope :find_comments_by_user, lambda { |user|
    where(:user_id => user.id).order('created_at DESC')
  }

  # Helper class method to look up all comments for
  # commentable class name and commentable id.
  scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
    where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
  }

  # Helper class method to look up a commentable object
  # given the commentable class name and id
  def self.find_commentable(commentable_str, commentable_id)
    commentable_str.constantize.find(commentable_id)
  end
end

Answer №1

If you're receiving console JS responses, it is likely that the issue can be found here:

comments.js.coffee

$(xhr.responseText).hide().insertAfter($(this)).show('slow') #-> Do you think this will work?

$(this).append xhr.responseText #-> Give this a try
alert xhr.responseText #-> Alternatively, consider using this approach

CommentsController

respond_to :js, :json, :html #-> Implementing cross-channel communication

def create 
     @comment = Comment.new(comment_params) #-> Following convention over configuration principles
     # If your comment belongs to a user, the `current_user` object is not needed.
     if @comment.save
         render :partial => "comments/comment", :locals => { :comment => @comment }, :layout => false, :status => :created
     else
         render :js => "alert('error saving comment');"
     end
  end

 def destroy
    @comment = Comment.find(params[:id])
    if @comment.destroy
      render :json => @comment, :status => :ok
    else
      render :js => "alert('error deleting comment');"
    end
  end

  private

  def comment_params
       params.require(:comment).permit(:title, :body, :etc)
  end

Answer №2

The issue arose when a user in development mode did not have all the necessary parameters, specifically the username was missing and only the email was present. I resolved this by including the following code:

<% if comment.user.username %> # Added a condition to check if the username is present before displaying it. This fix has resolved the issue and now everything is functioning smoothly. Previously, I was facing difficulties with one of the early users that I had created.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Linking the location of the pop-up to the currently selected text box

I am currently experimenting with setting the top and left values relative to the selected_element (which is active at the time of triggering the popup) in a manner similar to a tooltip. I attempted to use $().position() in combination with jQuery, but it ...

Mastering intricate data structures using React.js

I am working on creating a table for orders using React+Redux. The data I need is stored in props and it has a structured format similar to this: [{ //stored in props(redux state) "id": 37, //order 1 "content": { "items": { " ...

I'm encountering a npm error on Windows_NT 10.0.19042, does anyone know how to troubleshoot this issue?

After downgrading to [email protected], I encountered an error message that keeps popping up whenever I try to update npm or install new packages. What steps can I take to resolve this issue? npm ERR! Windows_NT 10.0.19042 npm ERR! argv "C:\ ...

FullCalendar dayClick event fails to trigger any action

I'm having trouble implementing the dayClick function in my fullCalendar. Despite setting up the calendar correctly, nothing happens when I click on a day. Here is the code I am using : var calendar; $(document).ready(function(){ app.init(); ...

How to efficiently use nested $.each() in DataTables with jQuery

After receiving Json data from the server, I utilize DataTables to display the information accordingly. The json contains multidimensional arrays with rows consisting of columns that may have more than one value. Here's an excerpt: { "info_table ...

Guide on positioning components to the right side of the NavigationDrawer in Vuetify with VueRouter

Working on my VueJS project, I've implemented a system to display content based on the user login using Firebase and Vuex state management. When a user is logged in, the content is shown using the v-if directive. Currently, I have successfully placed ...

Tips for preventing the colors of all buttons from changing when only one is clicked in JavaScript

const tasks = `[{ "taskName": "Task 1", "image": "./images/task1.jpg", "description": "Task 1 description", "importance": 0 }, { "taskName": "Task 2", "image": "./images/task2.jpg", "description": "Task 2 description", ...

What is the best way to include a div element with a dynamic animation on a webpage?

I'm attempting to create a laser beam that can shoot enemies on the screen, much like in classic games such as Space Invaders or Galaga. However, I am encountering difficulties getting the laser to move when I click the button. Below is the code I hav ...

Merge ReactCssTransitionGroup with React-route's Link to create smooth page transitions

React.js I'm facing an issue with the React.js code provided below. My goal is to set up the animation before transitioning to a new page using "React-router.Link" and ReactCSSTransitionGroup. Version: react: '15.2.1' react-addons-css-trans ...

rearranging the sequence of buttons using JavaScript

I am faced with the challenge of making a series of buttons draggable and droppable within a parent div without using any external libraries at the request of the client. Although I could have easily accomplished this task with jQuery, it's an opportu ...

React Redux encountered an issue with the absence of the 'Access-Control-Allow-Origin' header on the requested resource, causing the origin 'null' to be denied access

I am currently using React, Redux, and RoR in my app. I need to implement social login. On the client side, I am utilizing davezuko/react-redux-starter-kit, which is hosted on localhost:3000. My server is running on localhost:5000. All requests from the cl ...

Getting the expanded row columns values in a RadGrid when using the onHierarchyExpanded event

Here is the code for my RadGrid: <telerik:RadGrid ID="ProductRanges_Grd" ShowHeaderWhenEmpty="true" runat="server" AutoGenerateColumns="false" Width="100%" Height="250px" ShowHeader="true" Visible="false" ...

Encountering a mistake due to the anticipated atom not being found at the specified

In my react application, I am encountering an issue with allowing foreign characters along with English in the input field of a form. I have implemented a regular expression as follows: const alphabetRegex = /^([A-Za-z]+ )+[A-Za-z]+$|^[A-Za-z]*\p{L}/g ...

Capturing Ajax Success in Rails

After extensive googling, I have been unable to find my mistake. As a beginner with JS, this may be an easy fix for someone with more experience. Working with Rails 4. I am working on a modal that contains a form and I want to perform certain actions afte ...

The process of utilizing variables to form objects in ES6

My ES5 code contains a variable as shown below. var options = { clientId : clientId, keepAlive : keepAlive, clean : clean, reconnectPeriod : reconnectPeriod, will : lastWillMessage }; If I want to convert this to ES6, I can do so by writing ...

Interactive Map Displayed within a Pop-up Window

Recently, I developed a custom Google map where points are plotted and an HTML popup window appears when the image is clicked. Now, my goal is to open a file with JavaScript functions inside a lightbox/fancybox when a user clicks on an image. Below is th ...

Tips for retrieving a flag when there is a preexisting record within an association in Sequelize

I am working with a model A that has a 1:N association with a model B. My objective is to retrieve all records from A and determine whether there is at least one associated record from B (true) or not (false). The relationship setup: ModelA.hasMany(ModelB ...

Challenge with executing javascript library (photo sphere viewer)

I was excited to incorporate Photo Sphere Viewer into my project. After running npm i photo-sphere-viewer I noticed that the modules were successfully downloaded. Following that, I added this line inside my project: import PhotoSphereViewer from ' ...

Utilizing the map function in Angular while disregarding any null values

I have an array of objects in my dataset. Here's a glimpse of how it is structured: [ { "id": 1, "name": "john", "address": { "number": 42, "street": "High Street"} }, { ...

What are some ways to include additional data besides the new value in a change event for an input field?

Currently, I am using VueJS to dynamically generate a form based on a JSON schema and then attempting to save the data into my Vuex state. Here is an overview of the code I have written so far (simplified): <div v-for="field in schema" :key=& ...