0

I'm trying to implement Ajax for the first time in simple Rails app, helped mainly by this tutorial:

Integrating Ajax and Rails

My app has a particular show view where I want to display a leaderboard that renders a list of users and their record plus a form where new users/records can be created.

I'd like to achieve this via Ajax but every time I try to submit an Ajax request I get a 500 error pointing to the below JQuery line and throwing a 'Failed to load resource' message.

xhr.send( ( options.hasContent && options.data ) || null );  

I've tried to change a few things without success, including using remote:true in the form and making the Ajax request directly with JQuery. Could you point me to the potential problem here? Below the relevant code:

leaderboards_Controller Show action renders the relevant leaderboard

  def show
   @leaderboard = Leaderboard.find(params[:id])
   @leaders = @leaderboard.leaders
   @leader = Leader.new(persisted_time: @persisted_time)
  end

leaderboards/show.html.erb

  <%= simple_form_for([@leaderboard, @leader], html: { class: 'form-inline', id:'leader-form' }) do |f| %>
    <%= f.error_notification %>
    <div class="form-inputs">
      <%= f.input :name, :label => false, :placeholder => "Your name here", :required => true, :autofocus => true %>
      <%= f.input :record_time, :label => "Your record", input_html: {readonly: ''} %>
      <%= f.button :submit %>
    </div>
  <% end %>

  <ul>
  <% @leaders.each do |leader| %>
    <li>
      <%= leader.name %> |
      <strong>record: </strong><%= leader.record_time %> <br />
    </li>
  <% end %>
  </ul>

leaders_Controller I'm intending to send the Ajax request to the create action in this controller when submitting the form above

class LeadersController < ApplicationController
  before_action :set_leader, only: [:show, :edit, :update, :destroy]
  before_action :set_leaderboard, only: [:create, :new]

  def index
    @leaders = Leader.all
  end

  def show
  end

  def new
  end

  def edit
  end

  def create
     @leaderboard = Leaderboard.find(params[:leaderboard_id])
     @leader = Leader.new(leader_params)
     @leader.leaderboard_id = @leaderboard.id
     respond_to do |format|
        if @leader.save
          format.json { render json: @leader, status: :created}
        else
          format.json { render json: @leader.errors, status: :unprocessable_entity }
        end
     end
  end

  def update
    @leader.update_attributes(leader_params)
  end

  def destroy
    @leader.destroy
  end

  private
    def set_leader
      @leader = Leader.find(params[:id])
    end

    def set_leaderboard
      @leaderboard = Leaderboard.find(params[:leaderboard_id])
    end

    def leader_params
      params.require(:leader).permit(:name, :record_time, :leaderboard_id)
    end
end

assets/javascripts/leaders.js the JS file where I'm doing the Ajax request

$(function(){
  $("form").submit(function(event){
  event.preventDefault();

  var action = $(this).attr('action');
  var method = $(this).attr('method');

  var name = $(this).find('#leader_name').val();
  var record_time = $(this).find('#leader_record_time').val();

  $.ajax({
    method: method,
    url: action,
    data: { name: name, record_time: record_time }
  });

  });
});

and the routes

  resources :leaderboards, shallow: true do
   resources :leaders
  end

I'm clearly not getting something about Ajax. I'd appreciate if you point me to the right direction.

here's the output I get in the console after submiting the form

jquery.self-bd7ddd3….js?body=1:10255 POST http://localhost:3000/leaderboards/1/leaders 500 (Internal Server Error)

this leads to this line in the JQuery script:

xhr.send( ( options.hasContent && options.data ) || null );

and produces:

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

and server log

         Started POST "/leaderboards/1/leaders" for ::1 at 2016-11-28 21:42:24 +1100
Processing by LeadersController#create as JS
  Parameters: {"utf8"=>"✓", "leader"=>{"name"=>"9089sdas8dds", "persisted_time"=>"5"}, "commit"=>"S", "leaderboard_id"=>"1"}
  Leaderboard Load (0.5ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  Leaderboard Load (0.4ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  SQL (2.6ms)  INSERT INTO "leaders" ("name", "persisted_time", "leaderboard_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "9089sdas8dds"], ["persisted_time", "5"], ["leaderboard_id", 1], ["created_at", 2016-11-28 10:42:24 UTC], ["updated_at", 2016-11-28 10:42:24 UTC]]
   (2.2ms)  COMMIT
Completed 201 Created in 15ms (Views: 0.8ms | ActiveRecord: 5.9ms)


Started POST "/leaderboards/1/leaders" for ::1 at 2016-11-28 21:42:27 +1100
Processing by LeadersController#create as JS
  Parameters: {"utf8"=>"✓", "leader"=>{"name"=>"9089sdas8dds", "persisted_time"=>"5"}, "commit"=>"S", "leaderboard_id"=>"1"}
  Leaderboard Load (0.5ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.7ms)  BEGIN
  Leaderboard Load (0.5ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  SQL (1.9ms)  INSERT INTO "leaders" ("name", "persisted_time", "leaderboard_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "9089sdas8dds"], ["persisted_time", "5"], ["leaderboard_id", 1], ["created_at", 2016-11-28 10:42:27 UTC], ["updated_at", 2016-11-28 10:42:27 UTC]]
   (0.5ms)  COMMIT
Completed 201 Created in 14ms (Views: 1.0ms | ActiveRecord: 4.2ms)


Started POST "/leaderboards/1/leaders" for ::1 at 2016-11-28 21:42:29 +1100
Processing by LeadersController#create as JS
  Parameters: {"utf8"=>"✓", "leader"=>{"name"=>"9089sdas8dds", "persisted_time"=>"5"}, "commit"=>"S", "leaderboard_id"=>"1"}
  Leaderboard Load (0.6ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  Leaderboard Load (0.6ms)  SELECT  "leaderboards".* FROM "leaderboards" WHERE "leaderboards"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  SQL (2.3ms)  INSERT INTO "leaders" ("name", "persisted_time", "leaderboard_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "9089sdas8dds"], ["persisted_time", "5"], ["leaderboard_id", 1], ["created_at", 2016-11-28 10:42:29 UTC], ["updated_at", 2016-11-28 10:42:29 UTC]]
   (2.3ms)  COMMIT
Completed 201 Created in 14ms (Views: 0.7ms | ActiveRecord: 6.0ms)

2 Answers 2

1

Please update your code as below.

show.html.erb

<%= simple_form_for([@leaderboard, @leader],remote: true, html: { class: 'form-inline', id:'leader-form' }) do |f| %>
    <%= f.error_notification %>
    <div class="form-inputs">
      <%= f.input :name, :label => false, :placeholder => "Your name here", :required => true, :autofocus => true %>
      <%= f.input :record_time, :label => "Your record", input_html: {readonly: ''} %>
      <%= f.button :submit %>
    </div>
  <% end %>

  <ul>
  <% @leaders.each do |leader| %>
    <li>
      <%= leader.name %> |
      <strong>record: </strong><%= leader.record_time %> <br />
    </li>
  <% end %>
  </ul>

leaders_Controller

def create
   @leaderboard = Leaderboard.find(params[:leaderboard_id])
   @leader = Leader.new(leader_params)
   @leader.leaderboard_id = @leaderboard.id
   respond_to do |format|
    if @leader.save
      format.json { render json: @leader, status: :created}
    else
      format.json { render json: @leader.errors, status: :unprocessable_entity }
    end 
   end 
  end

assets/javascripts/leaders.js

$(function(){    
return $("#your-form-id").on("ajax:success", function(e, data, status, xhr) {
            e.preventDefault();
            // success code 
        }).on("ajax:error", function(e, xhr, status, error) {
            // error code
        });
});
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Hardik. I've tried your suggestion but unfortunately, as soon as I click the submit button I get the same error again (as described above). Any other clues?
can I see your backtrace?
sorry Hardik, I'm just a newbie when it comes to coding. I have no idea how to share that with you. If you guide me though I'd be happy to do it.
I'm not sure where I could retrieve more info on this. Could you point me to the right direction?
In your terminal on same tab where rails server is running
|
1

try adding

respond_to(:js)

at the end of your create method.

And yes, please just use remote: true

8 Comments

Thanks Fallenhero, unfortunately changing the create method can't help. It seems the request is not even reaching the method. I've also tried including remote: true in the form, as mentioned above, and the problem persists.
then please state the error message you are receiving
I'm getting the same error as posted in my question. I'll update the question to include the output I got in the console for further information on the error.
I see I'll post them above
there is an error in your controller, post complete code
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.