如何从多个表单字段中获取数据,然后将它们以相同的表单作为数组提交到单个数据库单元格中?

How can I get data from multiple form fields, and then submit them with the same form into a single database cell as a array?

这是我在 Rails 中的表格的一部分:

    # 2 fields that should have values passed into an array
    <%= f.label "test1" %>       
    <%= text_field_tag(:test1) %>
    <%= f.label "test2" %>
    <%= text_field_tag(:test2) %>

    # hidden field to (hopefully) receive the array data (same form)
    <%= f.hidden_field :subtypes, :value => @subtypes %>

这是我的控制器:

  def update
    if @anomaly.update(anomaly_params)
     redirect_to anomaly_path(@anomaly)
     flash[:success] = "You have successfully updated the anomaly"
    else
     render :edit
     flash[:error] = @anomaly.errors.full_messages
    end
  end

此方法将在各种方法之前运行:(before_action 在文件顶部)

# before_action :subtypes_array, only: [:new, :edit, :create, :update]

def subtypes_array
  @subtypes = []
  field1 = params[:test1]
  field2 = params[:test2]
  @subtypes << field1
  @subtypes << field2
end

我在控制器里也有这个:

# before_action :set_anomaly, only: [:show, :edit, :update, :destroy]
def set_anomaly
  @anomaly = Anomaly.find(params[:id])
end

我有 Rails 4 个强大的参数来允许来自各个领域的数据通过。 表单没有错误,但是 这两个字段的数据从未进入数据库。

我已经有一个数据库列可以接收带有字符串值的数组:

class AddSubtypesToAnomalies < ActiveRecord::Migration
  def change
    add_column :anomalies, :subtypes, :string, array: true, default: []
  end
end

从控制台我可以毫无问题地传递一个数组。

我想知道如何进行这项工作?

更新:

private
  def anomaly_params
    params.require(:anomaly).permit(:test1, :test2, :name, :description, :subtypes)
  end

你的text_field_tags需要嵌套在对象下

<%= text_field_tag("anomaly[test1]") %>
<%= text_field_tag("anomaly[test2]") %>

那是因为您使用的 form_for 设置了 异常 下的所有其他字段。 anomaly_params 仅在您的 update 方法中获取 anomaly 下面的内容。

更新

由于您在数据库字段中使用了一个数组,并且您选择为数组使用多个字段,因此您需要在创建和更新控制器方法中都捕获它。使用我在这里写的相同的 text_field_tags 你会这样做:

def create
  
  create_subtypes
  
  if @anmaly.save(anomaly_params)
  ...

def update

  create_subtypes

  if @anomaly.update(anomaly_params)
  ...

private
def create_subtypes
  params['anomaly']['subtypes'] = Array(params['anomaly']['subtypes']) << params['anomaly'].delete('test1')
  params['anomaly']['subtypes'] = Array(params['anomaly']['subtypes']) << params['anomaly'].delete('test2')
end

要解决数组开头的空项,请执行以下操作:

def create_subtypes
  params['anomaly']['subtypes'] = Array(params['anomaly']['subtypes'].presence).compact << params['anomaly'].delete('test1')
  params['anomaly']['subtypes'] = Array(params['anomaly']['subtypes'].presence).compact << params['anomaly'].delete('test2')
end

创建一个常规的 :subtypes 表单字段并让用户手动输入他们自己的逗号分隔列表而不是使用 test1 和 test2 可能更容易。

你必须告诉你的控制器 subtypes 参数是一个数组,否则它不会被这样处理,因为你有强参数,这是这样做的方法:

private
  def anomaly_params
    params.require(:anomaly).permit(:test1, :test2, :name, :description, :subtypes=> [])
  end

也为您的参数使用完整的散列标签

field1 = params[:anomaly][:test1]
field2 = params[:anomaly][:test2]