ActionController::Ошибка параметра (параметр отсутствует или значение пустое: JSON simple_form_for

#javascript #ruby-on-rails #json #ruby

#javascript #ruby-on-rails #json #ruby

Вопрос:

Я потратил полтора дня на поиск по всем подобным вопросам, но ни один из них не решает мою текущую проблему.

У меня есть простая форма, которая отображает форму javascript, и я получаю: ActionController::ParameterMissing (параметр отсутствует или значение пустое: referral): всякий раз, когда я пытаюсь отправить форму. Я пытался использовать выборку вместо require в своих параметрах, но это не исправляет проблему (ошибка не регистрируется, но и ничего не сохраняется).

Я перепробовал все, что мог придумать, и нахожусь в растерянности. Я использовал пример устаревшего кода для настройки формы, так что это, по сути, точно такой же формат, как форма, которая работает, поэтому я действительно не знаю, чего мне не хватает.

Я отображаю форму частично, поэтому в моих представлениях у меня есть:

просмотры / домовладельцы/ панель управления/показать.html.erb

 <%= render "homeowners/dashboard/referrals" %>

<div class="refer-resident-form hidden">
  <%= render 'referral_form' %>
</div>
  

просмотры / домовладельцы / панель мониторинга/рефералы.html.erb

 <div class="card article branded-border">
  <div class="refer-overlay">
    <div class="card-content refer-summary">
      <p class="larger"><%= t(".refer_developer") %></p>
      <p><%= t(".refer_description") %></p>
      <div class="refer-button">
      <%= button_tag t(".refer"), class: "btn branded-btn refer-resident",
      data: { cancel: t("edit.cancel"),
            cta: t(".send_invitation"),
            title: t(".refer")} %>
      </div>
    </div>
  </div>
</div>
  

просмотры / домовладельцы/ панель мониторинга/_referral_form.html.erb

 <div class="refer-description">
  <h4><%= t(".refer_description") %> </h4>
</div>

<%= simple_form_for @referral, url: homeowner_dashboard_path, remote: true do |f| %>
  <%= f.input :referee_first_name, label: t(".first_name"), required: true %>
  <%= f.input :referee_last_name, label: t(".last_name"), required: true %>
  <%= f.input :referee_email, label: t(".email"), required: true %>

  <%= f.hidden_field :referrer_name, value: (current_resident.first_name   " "   current_resident.last_name) %>
  <%= f.hidden_field :referrer_email, value: current_resident.email %>
  <%= f.hidden_field :referral_date, value: Time.now %>
<% end %>
  

Мой контроллер controllers/домовладельцы/referrals_controller.rb

 module Homeowners
  class ReferralsController < Homeowners::BaseController

    def create
      create_new_referral
    end

    private

    def create_new_referral
      @referral = Referral.new(referral_params)
      redirect_to root_path
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def referral_params
      params.require(:referral).permit(
        :referee_first_name, :referee_last_name, :referee_email, :referral_date,
        :referrer_name, :referrer_email
      )
    end
  end
end
  

И мой файл javascript refer.js (пожалуйста, имейте в виду, что я ничего не знаю о javascript и, по сути, скопировал этот код из другой формы, просто внеся незначительные изменения, чтобы сделать его актуальным)

 (function (document, $) {
  'use strict'

  $(document).on('click', '.refer-resident', function (event) {
    var dataIn = $(this).data()

    var $referContainer = $('.refer-resident-form')

    $('body').append($referContainer)
    var $form = $('.refer_resident')

    $referContainer.dialog({
      show: 'show',
      modal: true,
      width: 700,
      title: dataIn.title,
      buttons: [
        {
          text: dataIn.cancel,
          class: 'btn',
          click: function () {
            $(this).dialog('destroy')
          }
        },
        {
          text: dataIn.cta,
          class: 'btn-send btn',
          id: 'btn_submit',
          click: function () {
            // Clear any old messages before the post
            $('.flash').empty()

            $.post({
              url: '/homeowners/referral',
              data: $form.serialize(),
              dataType: 'json',
              success: function (response) {
                var $responseP = document.createElement('p')
                if (response.alert === null) {
                  $responseP.className = 'notice'
                  $responseP.innerHTML = response.notice
                } else {
                  // If there are both alert and notice responses, only show the alert
                  $responseP.className = 'alert'
                  $responseP.innerHTML = response.alert
                }
                $('.flash').append($responseP)
                $(window).scrollTop(0)
              }
            })
            $(this).dialog('destroy')
            $referContainer.hide()
          }
        }]
    }).prev().find('.ui-dialog-titlebar-close').hide() // Hide the standard close button

    validateSendReferral()
  })

  $(document).on('input', '.refer-resident-form', function (event) {
    validateSendReferral()
  })

  function validateSendReferral () {
    if (($('input#referral_referee_first_name').val().length > 0)
        amp;amp; ($('input#referral_referee_last_name').val().length > 0) amp;amp; validateEmail()) {
      $('.btn-send').prop('disabled', false)
      $('.btn-send').removeClass('ui-state-disabled')
    } else {
      $('.btn-send').prop('disabled', true)
      $('.btn-send').addClass('ui-state-disabled')
    }
  }

  function validateEmail () {
    var re = /S @S .S /
    return re.test($('input.email').val())
  }

})(document, window.jQuery)
  

Кто-нибудь может сказать мне, где я ошибаюсь или чего мне не хватает, пожалуйста?

Редактировать:

Когда я отправляю форму, я получаю следующий вывод

    (0.2ms)  BEGIN
   (0.2ms)  COMMIT
Started POST "/homeowners/referral" for ::1 at 2019-04-01 12:40:41  0100
Processing by Homeowners::ReferralsController#create as JSON
  Resident Load (0.6ms)  SELECT  "residents".* FROM "residents" WHERE "residents"."id" = $1 ORDER BY "residents"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
   (0.7ms)  SELECT COUNT(*) FROM "resident_notifications" WHERE "resident_notifications"."resident_id" = $1 AND "resident_notifications"."read_at" IS NULL  [["resident_id", 2]]
  Plot Load (0.5ms)  SELECT  "plots".* FROM "plots" WHERE "plots"."deleted_at" IS NULL AND "plots"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Developer Load (0.5ms)  SELECT  "developers".* FROM "developers" WHERE "developers"."deleted_at" IS NULL AND "developers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.3ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Development Load (0.3ms)  SELECT  "developments".* FROM "developments" WHERE "developments"."deleted_at" IS NULL AND "developments"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Brand Load (0.3ms)  SELECT  "brands".* FROM "brands" WHERE "brands"."brandable_id" = $1 AND "brands"."brandable_type" = $2 LIMIT $3  [["brandable_id", 1], ["brandable_type", "Development"], ["LIMIT", 1]]
Completed 400 Bad Request in 24ms (ActiveRecord: 3.1ms)



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

app/controllers/homeowners/referrals_controller.rb:23:in `referral_params'
app/controllers/homeowners/referrals_controller.rb:17:in `create_new_referral'
app/controllers/homeowners/referrals_controller.rb:11:in `create'
  

Комментарии:

1. Похоже, проблема с передачей параметров из формы в контроллер. Не могли бы вы, пожалуйста, обновить свой вопрос журналами для запроса, который создает новую ссылку?

Ответ №1:

Похоже, что вы пытаетесь сериализовать форму с помощью селектора jQuery, который, возможно, на самом деле не нацелен на форму. В частности, вы вызываете

 var $form = $('.refer_resident')
  

и затем

 $.post({
  ...
  data: $form.serialize(),
  

но я не вижу, чтобы вы специально предоставляли форме этот класс, и я не думаю, что simple_form сгенерирует этот класс для вас. Я считаю, что он будет генерировать классы типа .new_referral и .edit_referral на основе наличия атрибута id. Вы можете либо явно назначить этот класс, либо просто использовать встроенный класс.

Комментарии:

1. Спасибо, проблема оказалась в JavaScript. Я нацеливался не на тот контейнер. Сейчас мои параметры проходят, просто не сохраняются в базе данных. Надеюсь, это будет легче выяснить.