Rails activeadmin сохраняет данные в связанной таблице

У меня есть одна таблица для продуктов, и продукт может быть либо внутри, либо снаружи, либо в обоих случаях. Поэтому я создал еще одну таблицу, чтобы сохранить местоположение продуктов. Теперь, когда администратор добавляет продукт, я предоставил возможность выбрать местоположение (я), в котором может находиться продукт, но когда он публикуется, код говорит, что поле не может быть пустым из-за проверки. Я не уверен, что мне не хватает или подход неправильный.

Модель продукта:

class Product < ApplicationRecord
  validates :name, presence: true      

  has_many :product_locations

  accepts_nested_attributes_for :product_locations
end

Модель местоположения продукта:

class ProductLocation < ApplicationRecord

  enum locations: [:exterior, :interior]

  validates :location, presence: true
  validates :product_id, presence: true

  belongs_to :product
end

Файл ActiveAdmin для продукта:

ActiveAdmin.register Product do

  permit_params :name, product_locations_attributes: {}

  actions :all, except: [:show, :destroy]

  filter :name

  index do        
    column 'Product Name',  :name
    actions
  end

  form do |f|
    f.semantic_errors *f.object.errors.keys

    f.inputs "Products" do
      f.input :name          
    end

    f.has_many :product_locations do |location|
      location.inputs "Locations" do
        location.input :location, as: :select, multiple: true, collection: ProductLocation.locations.keys
      end
    end

    f.actions
  end

  controller do
    def scoped_collection
      Product.where(user_id: nil)
    end
  end

end

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

Ошибка при сохранении клика, которую я получаю:

Укажите местоположение.

Параметры, которые публикуются:

Parameters: {"utf8"=>"✓", "product"=>{"name"=>"Test Product", "product_locations_attributes"=>{"0"=>{"location"=>["0", "1"]}}}, "commit"=>"Create Product"}

person Deepanshu Goyal    schedule 02.06.2017    source источник
comment
Какая точная ошибка? Обновите его в вопросе.   -  person Pavan    schedule 05.06.2017
comment
@Паван, пожалуйста, проверь   -  person Deepanshu Goyal    schedule 05.06.2017
comment
Я думаю, вам следует изменить permit_params :name, product_locations_attributes: {} на permit_params :name, product_locations_attributes: [:location]   -  person Pavan    schedule 05.06.2017
comment
Я думаю, что эта строка location.input :location, as: :select, multiple: true, collection: ProductLocation.locations.keys должна быть location.input :location, as: :select, multiple: true, collection: ProductLocation.locations, так как .keys не будет присутствовать в массиве.   -  person Sravan    schedule 05.06.2017
comment
@Pavan, но потом пишет Недопустимый параметр: :location   -  person Deepanshu Goyal    schedule 05.06.2017
comment
Виноват. Это должно быть permit_params :name, product_locations_attributes: [location: []], так как у вас есть множественный выбор.   -  person Pavan    schedule 05.06.2017
comment
@Pavan Он сохраняет данные, если я сохраняю обычный выбор, если я отмечаю его как множественный выбор, то выдает ошибку. Есть ли что-то еще, что нужно сделать?   -  person Deepanshu Goyal    schedule 05.06.2017
comment
обычный выбор с помощью location: [] или :location?   -  person Pavan    schedule 05.06.2017
comment
@Pavan с любым из вариантов ..   -  person Deepanshu Goyal    schedule 05.06.2017
comment
Можете ли вы обновить вопрос с параметрами, сгенерированными с помощью исходного кода?   -  person Pavan    schedule 05.06.2017
comment
@Pavan Пожалуйста, проверьте   -  person Deepanshu Goyal    schedule 05.06.2017
comment
Давайте продолжим это обсуждение в чате.   -  person Pavan    schedule 05.06.2017


Ответы (1)


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

product_locations_attributes: [:id, :location]

Затем в вашей форме

location.input :location, as: :select, multiple: true, collection: ProductLocation.locations.keys

Поскольку ProductLocation.locations — это массив, array.keys — недопустимый метод.

Итак, используйте непосредственно

location.input :location, as: :select, multiple: true, collection: ProductLocation.locations.map { |n| [n,n] }

Чтобы сохранить массив из нескольких значений, возьмите поле serialize как массив,

class ProductLocation < ApplicationRecord

  enum locations: [:exterior, :interior]

  serialize :location, Array

  validates :location, presence: true
  validates :product_id, presence: true

  belongs_to :product
end

Примечание. Чтобы сериализация работала, вам нужно, чтобы dataType местоположения было text. Если это не text, запустите миграцию, чтобы изменить тип данных на text.

Причина для текстового поля: Rails преобразует все эти объекты в обычный текст при сохранении в базе данных.

person Sravan    schedule 05.06.2017
comment
@DeepanshuGoyal, у вас должен быть тип поля serialize для хранения нескольких значений. - person Sravan; 05.06.2017
comment
Я получаю эту ошибку: не могу сбросить section: должен был быть массивом, но был целым числом. -- 0 - person Deepanshu Goyal; 05.06.2017
comment
хорошо, понял, измени коллекцию на ProductLocation.locations.map { |n| [n,n] } - person Sravan; 05.06.2017
comment
Но это все еще дает мне ошибку, не может сбросить раздел: должен был быть массив, но был целым числом. -- 0 - person Deepanshu Goyal; 05.06.2017
comment
Давайте продолжим это обсуждение в чате. - person Deepanshu Goyal; 05.06.2017