Rails,将数组提交给postgres

问题描述

我有一个Rails API,我试图将一个数字数组传递给我的postgres db,但是我不能:我发送一个带有两个值的数组,并且它接受一个只有第一个值的数组。

我有2个模型,ItinaryEvent,其中:

class Event 
  belongs_to: itinary
  accepts_nested_attributes_for :itinary

class Itinary
   has_many: events

我在Postgres中使用Postgres和React前端以及Rails API。我用array类型的值声明了decimal类型的列:

  • Rails Postgres模式:我将DECIMAL设置为类型:
create_table "itinaries",force: :cascade do |t|
    ...
    t.decimal "start_gps",default: [],array: true
  • 滑行EventsController:从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的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无法读取逗号“,”,该逗号将数组中的两个值分开。

解决方法

您可能想尝试一下:

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
   }
,

如果有兴趣,可以“手动”解决:将数字数组保存到数组字段中,我将接收到的参数拆分。这是不令人满意的,因为这样简单的工作需要很多手势。我仍然看不到有什么问题。

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

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)
...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...