Rails activeadmin 在关联 table 中保存数据

Rails activeadmin save data in associated table

我有一个 table 用于产品,产品可以在内部或外部或两者兼而有之。所以我创建了另一个 table 来保存产品位置。现在,当管理员添加产品时,我已经向 select 提供了产品可以位于的位置的选项,但是当它被发布时,代码说由于验证,该字段不能为空。我不确定我遗漏了什么或方法有误。

产品型号:

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

我得到一个 multi-select 用于 "Interior" 和 "Exterior" 用于 selection 的位置,但它说字段不能为空时我select位置并提交表格

点击保存时出现的错误是:

Location can't be blank

发布的参数是:

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

首先,许可属性应该是,

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 将所有这些对象存储在数据库中时将其转换为纯文本