Работа с массивами Rails в Postgres

У меня есть столбец postgres с именем content, который представляет собой массив.

Но при попытке использовать его в форме я получаю:

не могу привести ActionController::Parameters к тексту

Несмотря на то, что вывод выглядит довольно хорошо:

{"utf8"=>"✓",
 "_method"=>"patch",
 "authenticity_token"=>"NkK4BggxknfEn0A8shTs06xmesERaZdYtZdl9oEEUTk=",
 "notification_template"=>{"content"=>{"0"=>"Join us {{event_time}} {{{twitter_name}}} to win Big! hint: {{{question}}} #quiz {{location_tags}} {{url}} sdfsdfsdf"}},
 "commit"=>"Update Notification template",
 "id"=>"25"}

сильные параметры

params.require(:notification_template).permit(:name, :content => {})

маршруты

resources :notification_templates do
  get 'edit/:id', to: 'notification_templates#edit_content', as: 'edit_content'
end

контроллер

  def edit_content
    @notification_template = NotificationTemplate.find(params[:notification_template_id])
  end

  def update
    if @notification_template.update(notification_template_params)
      redirect_to admin_notification_template_path(@notification_template), notice: 'Social message was successfully updated.'
    else
      render action: 'edit'
    end
  end

моя форма

URL-адрес выглядит так: /notification_templates/25/edit_content/7 # пользовательское действие, но использует обычное обновление

<%= simple_form_for([:admin, @notification_template]) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.simple_fields_for :content do |fields| %>
        <%= fields.input params[:id], input_html: { value: @notification_template.content[params[:id].to_i] } %>
    <% end %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>

<% end %>

столбец БД

add_column :notification_templates, :content, :text, array: true, default: []

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

add_column :notification_templates, :content, :text, array: true, default: []
add_column :notification_templates, :content, :sting, array: true, default: []
add_column :notification_templates, :content, :text, array: true, default: {}

Я выбираю первый на том основании, что строка не позволяет использовать столько символов, сколько мне может понадобиться, а текст более удобен. Также по умолчанию [] против {} или '{}'

Но в postgres см. content text[] DEFAULT '{}'::text[]

журнал

Started PATCH "/admin/notification_templates/25" for 127.0.0.1 at 2014-11-28 14:25:43 +0100
Processing by Admin::NotificationTemplatesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"NkK4BggxknfEn0A8shTs06xmesERaZdYtZdl9oEEUTk=", "notification_template"=>{"content"=>{"4"=>"{{{question}}} Study up and stop by {{{twitter_name}}} {{event_time}} for a #quiz {{location_tags}} {{url}} sdfsdfsdf"}}, "commit"=>"Update Notification template", "id"=>"25"}
  User Load (0.9ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  NotificationTemplate Load (0.5ms)  SELECT  "notification_templates".* FROM "notification_templates"  WHERE "notification_templates"."id" = $1 LIMIT 1  [["id", 25]]
   (0.3ms)  BEGIN
   (0.3ms)  ROLLBACK
Completed 500 Internal Server Error in 54ms
Reporting exception: can't cast ActionController::Parameters to text

TypeError (can't cast ActionController::Parameters to text):
  app/controllers/admin/notification_templates_controller.rb:40:in `update'


  Rendered /Users/holden/.rvm/gems/[email protected]/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.1ms)
  Rendered /Users/holden/.rvm/gems/[email protected]/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
  Rendered /Users/holden/.rvm/gems/[email protected]/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.4ms)
  Rendered /Users/holden/.rvm/gems/[email protected]/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (27.5ms)

ОБНОВИТЬ

Я также заметил, что поле типа массива обновления не работает должным образом в консоли.

например. если я попытаюсь обновить член массива, something = record.content[2] = 'blah' это сработает. Но когда я сохраняю запись, она не обновляется.


comment
эй, это, кажется, работает! У меня эта часть работает, спасибо.   -  person ere    schedule 28.11.2014
comment
укажите полный журнал трассировки со строкой исключения   -  person Малъ Скрылевъ    schedule 28.11.2014
comment
покажите код вокруг строки: `app/controllers/admin/notification_templates_controller.rb`   -  person Малъ Скрылевъ    schedule 28.11.2014
comment
попробуйте @notification_template.update(notification_template_params.to_h)   -  person Малъ Скрылевъ    schedule 28.11.2014
comment
убедитесь, что notification_template_params разрешены некоторые обязательные параметры   -  person Малъ Скрылевъ    schedule 28.11.2014


Ответы (1)


Да, массивы Postgres в Rails все еще немного шаткие. Hstore немного проще.

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

eg.

def content_member=(member)
    unless member.blank?
        self.content_will_change!
        self.content[member.keys.first.to_i] = member.values.first
    end
end

Вам также необходимо сообщить рельсам, если вы собираетесь обновить член массива, поэтому это не работает в консоли.

Здесь есть полное объяснение:

Тип данных массива Rails 4 Postgresql: обновление значений

person holden    schedule 28.11.2014