Rails,将数组提交给postgres



我有一个Rails API,我试图将一个数字数组传递到我的postgres数据库,但我做不到:我发送一个带有两个值的数组,它只接受一个带有第一个值的阵列。

我有两个型号,ItinaryEvent,其中:

class Event 
belongs_to: itinary
accepts_nested_attributes_for :itinary
class Itinary
has_many: events

我使用Postgres和React前端,并使用Rails API和Postgres。我声明了一个array类型的列,如果类型为decimal:

  • Rails Postgres模式:我将DECIMAL设置为类型:
create_table "itinaries", force: :cascade do |t|
...
t.decimal "start_gps", default: [], array: true
  • RailsEventsController:没有什么花哨的,从Event控制器来看,创建方法是:Event.new(event_params),强params方法也相当简单:
def event_params
params.require(:event).permit( 
...,
itinary_attributes: [...,  start_gps: [] ],
...
)
end

我检查了Event.first.itinary.start_gps.class是否返回Array。我可以用Itinary.create!(..., start_gps:[45,1])播种(数值是数字(。

  • React表单:数据在React的FormData中发送,我相信我使用了正确的Rails命名约定:
const fdata = new FormData()
fdata.append("events[itinary_attributes][start]", itinary.start)
fdata.append("events[itinary_attributes][start_gps][]", itinary.start_gps)
...

所以我POST请求的标题包含:

event[itinary_attributes][start_gps][]: 45.1936513315257,0.6646728515625

在提交时,我几乎得到了所需的参数,但数组中的值被引用:

Parameters: 
{"event"=>{
"itinary_attributes"=>{
"date"=>"2020-08-16",
"start"=>"Paris FRA",
"start_gps"=>["48.85011347181819,2.3353889957070355"], << one value ?
}
}
}

所以当Postgres触发时,我只得到第一个值:

Itinary Create (2.5ms)  
INSERT INTO "itinaries" ...
["start_gps", "{48.85011347181819}"], <<<<< ONLY FIRST
^^
]
  • 如果我将t.stringt.text设置为架构中的数据类型,Postgres将触发:
Itinary Create (2.5ms) 
["start_gps", "{"45.18978009667531,0.6811523437500001"}"]]

因此Event.last.itinary.start_gps.length返回1,一个级联值:

start_gps: Array(1)
=> "45.158800738352106,1.5051269531250002"

我甚至尝试从React提交一组字符串,但没有成功。从哪里开始?我相信这是非常经典的东西。看起来Rails或Postgres无法读取逗号",该逗号用于分隔数组中的两个值。

如果感兴趣,可以"手动"解决这个问题:要将一个数字数组保存到数组字段中,我会拆分收到的params。这是不令人满意的,因为这么简单的工作需要这么多手势。我仍然不明白出了什么问题。

一种解决方案是添加控制器:

if params[:event][:itinary_attributes][:start_gps]
params[:event][:itinary_attributes][:start_gps] = params[:event][:itinary_attributes][:start_gps][0].split(',')
end
event_params = params.require(:event).permit( 
...,
itinary_attributes: [...,:start, start_gps: [], end_gps: []],  
) 
Event.new(event_params)
...

你可能想试试这个:

const fdata = new FormData()
fdata.append("events[itinary_attributes][start]", itinary.start)
fdata.append("events[itinary_attributes][start_gps][]", itinary.start_gps[0])
fdata.append("events[itinary_attributes][start_gps][]", itinary.start_gps[1])

这应该会让你

{"event"=>{
"itinary_attributes"=>{
"date"=>"2020-08-16",
"start"=>"Paris FRA",
"start_gps"=>["48.85011347181819", "2.3353889957070355"] <-- Two values in an array
}

相关内容

  • 没有找到相关文章

最新更新