Редактировать данные JSONB в поле формы textarea - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть поле JSONB на моей модели, пользователи могут использовать CRUD через мой API. Это все отлично работает.

Я бы хотел предоставить внутреннему персоналу / администратору возможность редактировать объект настроек JSON через поле формы textarea. (Пользователи технически подкованы и будут знать, как написать правильный JSON.)

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

Я вижу параметры настройки отправлено:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"bla_bla_bla", "users_notification"=>{"user_id"=>"48", "report_id"=>"2", "status"=>"1", "frequency"=>"1", "settings"=>"{\"threshold\"=>\"50\"}"}, "commit"=>"Update Users notification", "id"=>"18"}

и я на 99% уверен, что правильно внес в белый список параметры:

def users_notification_params
  params.require(:users_notification).permit(
    :user_id,
    :report_id,
    :status,
    :frequency,
    :settings,
    settings: [:threshold, :products, :avg_sales]
  )
end

Однако, когда я вывожу users_notification_params с путами, я вижу, что настройки равны nil:

{"user_id"=>"48", "report_id"=>"2", "status"=>"1", "frequency"=>"1", "settings"=>nil}

Я подумал, что мне нужно проанализировать параметр настройки, чтобы установить обратный вызов before_action, но при выводе users_notification_params я все равно вижу "settings"=>nil, поэтому мне нечего анализировать.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Вместо того, чтобы дать администратору возможность изменять текстовое поле, вы можете дать форме дополнительные поля для ваших настроек:

<%= form_with(model: users_notification, local: true) do |form| %>
   <%= form.fields_for(:settings) do |sf| %>
      <div class="field">
        <%= sf.label :threshold %>
        <%= sf.number_field :threshold %>
      </div>
   <% end %>

   ...

<% end %>

При этом параметры будут выглядеть как

{"users_notification"=>{"settings"=>{"threshold"=>"1"}}

Это будет работать с вашим permit.

0 голосов
/ 01 ноября 2018

Я думаю, что проблема в том, что Rails не автоматически разбирает строку JSON в хеш, и вы пытаетесь внести белый список в хеш. Попробуйте удалить settings: [:threshold, :products, :avg_sales]. Затем вам нужно проанализировать JSON в модели или в контроллере.

class Thing < ApplicationRecord
  def settings=(val)
    if val.is_a?(String)
      begin 
        super JSON.parse(val)
      rescue JSON::ParserError
        errors[:settings].add('is not valid JSON')
        super
      end
    end
  end
end

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

...