简体   繁体   中英

Rails forms and AJAX 400 bad request issue

I am trying to submit a new "tweet" through a rails form_for, and handling with AJAX. I am continually getting a 400 Bad request problem. Despite this, the tweet is still posting and the server is returning a 200. Please help?

The error is

Started POST "/tweets" for ::1 at 2016-07-10 20:20:21 -0400 Processing by TweetsController#create as HTML Completed 400 Bad Request in 2ms (ActiveRecord: 0.0ms)

ActionController::ParameterMissing (param is missing or the value is empty: tweet):

tweets.js

$(function(){

  //grab the click event
  $('#new_tweet').on('submit', function(e){
    var valuesToSubmit = $(this).serialize;
    console.log('point one')
    //var self = $(this)
    e.preventDefault();
    $('.tweets').html('');

    //start ajax function
        $.ajax({
          url: $(this).attr('action'),
          method: 'POST',
          data: valuesToSubmit,
          dataType: 'html'
        });
  });// end of click event
}); //end of on load function

Tweets controller#create

def create
@tweet = Tweet.new(tweet_params)

if @tweet.save
  if request.xhr?
    render @tweet, layout: false
  else
    redirect_to root_path
  end
else
  render :index
end

tweet_params action

private

def tweet_params
  params.require(:tweet).permit(:message)
end

Tweets index view

<ul class="tweets">
  <% @tweets.each do |tweet| %>
    <li class="tweet">
      <p><%= tweet.message %></p>
      <time><%= tweet.created_at.strftime('%b %e, %l:%M %p') %></time>
    </li>
  <% end %>
</ul>

<%= form_for @tweet, remote: true do |f| %>
  <%= f.text_area :message, placeholder: "What did you learn today?" %>
  <%= f.submit "Tweet", id: "create-tweet" %>
<% end %>

Thanks for all the help StackOverFlow!

Because the tweet is saved properly as you said, I reckon the issue is to do with ajax response or this line particularly render @tweet, layout: false . Do you want to try my suggestion below?

Instead of returning response in html , let Rails generate a js response for you.

Controller:

def create
  @tweet = Tweet.new(tweet_params)
  if @tweet.save
    respond_to do |format|
      format.js
      format.html { redirect_to root_path }
    end
  else
    respond_to do |format|
      format.js { alert("Error"); }
      format.html { render :index }
    end   
  end
end

JS:

$.ajax({
  url: $(this).attr('action'),
  method: 'POST',
  data: valuesToSubmit
});

Create a file called create.js.erb under tweets folder. When the app return js response(either success or failure), you can manipulate the DOM within this file like this:

var time = "<time><%= @tweet.created_at.strftime('%b %e, %l:%M %p') %></time>";   
$('.tweets').append("<li class='tweet'>" + "<%= @tweet.message %>" + time + "</li>");

Hope that helps. Cheers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM