Rails Ajax为编辑视图调用404错误

时间:2018-03-16 13:05:07

标签: ruby-on-rails ajax

我的新视图和编辑视图上有一个按钮,通过Ajax调用向我的Letter控制器发送一个帖子请求。如果Ajax调用在新视图中完美运行,则会为我的编辑视图抛出404错误。

路线:

  post 'letters/ajax_send_test_botletter', to: 'letters#send_test_botletter', as: 'send_test_botletter'

表单的定义如下:

<%= form_for(letter, :html => {class: "directUpload", remote: true}) do |f| %>

按钮以以下形式触发Ajax调用:

<button class="cta3" id="send_test_letter">Send a test campaign to yourself</button>

Ajax电话:

  $('#send_test_letter').on('click', function(){
    $('form').submit(function() {
      var valuesToSubmit = $(this).serialize();
      $.ajax({
          type: "POST",
          url: "/letters/ajax_send_test_botletter",
          data: valuesToSubmit,
          dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
      }).success(function(json){
          if(json['value'] == "No Recipient") {
            $('#send_test_letter').css('display', 'none');
            $('#save_test_user').css('display', 'block');
          } else {
            console.log("Success")
            $('#confirmation_test_sent').html('Test successfully sent. Check your Messenger.')
          }
          $('form').unbind('submit');
      });
      return false; // prevents normal behaviour
    });
  });

我的send_test_botletter方法

def send_test_botletter

    @message_content = params[:letter]['messages_attributes']['0']['content']

    @button_message = params[:letter]['messages_attributes']['0']['buttons_attributes']['0']['button_text'] if params[:letter]['messages_attributes']['0']['buttons_attributes']['0']['button_text'] != ''
    @button_url = params[:letter]['messages_attributes']['0']['buttons_attributes']['0']['button_url'] if params[:letter]['messages_attributes']['0']['buttons_attributes']['0']['button_url'] != ''
    @cards = params[:letter]['cards_attributes'] if params[:letter]['cards_attributes'].present? == true

    @test_segment = Segment.where(core_bot_id: @core_bot_active.id, name: "test").first
    @recipients = BotUser.where(core_bot_id: @core_bot_active.id, source: @test_segment.token)

    if @recipients.exists?
      send_message_onboarding if @message_content != '' and @button_message.present? == false
      send_message_button_onboarding if @message_content != '' and @button_message.present? == true and @button_url.present? == true
      send_card_onboarding if @cards

      respond_to do |format|
        format.json { render json: {"value" => "Success"}}
      end
    else
      respond_to do |format|
        format.json { render json: {"value" => "No Recipient"}}
      end
    end
  end

我在Chrome控制台中收到了以下针对编辑视图的错误:

  

POST http://localhost:3000/letters/ajax_send_test_botletter 404(不是   实测值)

在我的Rails日志中:

  

ActiveRecord :: RecordNotFound(无法找到带有的信件   &#39; ID&#39; = ajax_send_test_botletter):

它似乎调用了Update方法而不是send_test_botletter方法......

知道这里有什么问题吗?

2 个答案:

答案 0 :(得分:1)

我找到了诀窍。问题是编辑表单中的PATCH方法。

我在this discussion中找到了一个插件,用于修改序列化数据并将方法更改为“post”:

$('#send_test_letter').on('click', function(){
    $('form').submit(function() {
      var valuesToSubmit = $(this).awesomeFormSerializer({
          _method: 'post',
      });
      $.ajax({
          type: "POST",
          url: "/letters/ajax_send_test_botletter",
          data: valuesToSubmit,
          dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
      }).success(function(json){
          if(json['value'] == "No Recipient") {
            $('#send_test_letter').css('display', 'none');
            $('#save_test_user').css('display', 'block');
          } else {
            console.log("Success")
            $('#confirmation_test_sent').html('Test successfully sent. Check your Messenger.')
          }
          $('form').unbind('submit');
      });
      return false; // prevents normal behaviour
    });
  });

(function ( $ ) {
    // Pass an object of key/vals to override
    $.fn.awesomeFormSerializer = function(overrides) {
        // Get the parameters as an array
        var newParams = this.serializeArray();

        for(var key in overrides) {
            var newVal = overrides[key]
            // Find and replace `content` if there
            for (index = 0; index < newParams.length; ++index) {
                if (newParams[index].name == key) {
                    newParams[index].value = newVal;
                    break;
                }
            }

            // Add it if it wasn't there
            if (index >= newParams.length) {
                newParams.push({
                    name: key,
                    value: newVal
                });
            }
        }

        // Convert to URL-encoded string
        return $.param(newParams);
    }
}( jQuery ));

答案 1 :(得分:0)

form_for(letter...生成不同的网址和方法,具体取决于实例是否保留,默认为createpostupdatepatch

当你点击提交时,它会尝试点击此端点,在你的听众开始之前。这样做会打破其余的js。

但是,您还可以向url提供methodform_for个选项。尝试提供空白的url选项和正确的方法(form_for letter, ..., url: '', method: :post)。

或者,您可以在表单提交时停止默认行为/传播:

$('form').submit(function(e) { 
  e.stopPropagation() // Or could simply be `preventDefault()`, depending on your use case
  ...
  // your AJAX
}

能够测试这些方法吗?

<强>更新

您的方法实际上是在submit内嵌套click侦听器。请尝试以下方法:

  $('#send_test_letter').on('click', function(e){
    e.stopPropagation()
    var $form = $(this).closest('form')
    var valuesToSubmit = $form.serialize();
    $.ajax({
        type: "POST",
        url: "/letters/ajax_send_test_botletter",
        data: valuesToSubmit,
        dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
    }).success(function(json){
        if(json['value'] == "No Recipient") {
          $('#send_test_letter').css('display', 'none');
          $('#save_test_user').css('display', 'block');
        } else {
          console.log("Success")
          $('#confirmation_test_sent').html('Test successfully sent. Check your Messenger.')
        }
      return false; // prevents normal behaviour
    });
  });