未转换为整数数组的字符串数组

时间:2015-02-20 14:24:34

标签: ruby-on-rails arrays

我试图理解以下行为:

irb(main):016:0* pg = ProductGroup.find(1)
irb(main):017:0> pg.good_type_ids
=> [1]
irb(main):018:0> pg.update({"good_type_ids"=>["", "1"]})
irb(main):019:0> pg.changed?
=> false
irb(main):020:0> pg.good_type_ids
=> ["1"]

上面的代码模仿了表单更新。 good_type_ids是多选的ids。虽然数组的值从[1]变为[" 1"],但是改变了?方法返回false。更新方法似乎也足够聪明,可以删除空字符串。

irb(main):021:0> pg = ProductGroup.find(1)
irb(main):022:0> pg.good_type_ids
=> [1]
irb(main):023:0> pg.attributes = {"good_type_ids"=>["", "1"]}
=> {"good_type_ids"=>["", "1"]}
irb(main):024:0> pg.changed?
=> true
irb(main):025:0> pg.good_type_ids
=> ["", "1"]

在第二个例子中,我尝试将更改的参数从表单应用到对象。我不想把它保存到dbs! 不知何故,属性方法的行为与更新方法不同,并且在调用方法后,good_type_ids将是[""," 1"]。

似乎dbs中的列类型被"更新"考虑在内。和"属性"方法,仅适用于阵列(postgress),这似乎不起作用。

irb(main):030:0* pg.attributes = {"recourse_days"=>5}
=> {"recourse_days"=>5}
irb(main):031:0> pg.changed?
=> true
irb(main):039:0* pg.recourse_days
=> 5

recourse_days定义为整数,在post期间,控制器接收一个字符串并将其正确转换为整数。

Schema.rb:t.integer" good_type_ids",默认:[],数组:true

作为临时工作,我把它放在控制器的更新方法中

params["good_type_ids"].reject!(&:blank?)
params["good_type_ids"].map!(&:to_i)    

1 个答案:

答案 0 :(得分:-1)

UPD

字符串转换问题和保存到pgsql的零元素似乎在rails 4.2.0中得到修复,我听说整个类型的转换系统在那里进行了大量的修改:

> doc.test_digit = ["1"] #=> ["1"] 
> doc.test_digit #=> [1] 
> doc.test_string #=> ["2"] 
> doc.test_string = [2] #=> [2] 
> doc.test_string #=> ["2"]
>   doc.attributes = {'test_digit'=>["", "2"]}
 => {"test_digit"=>["", "2"]} 
> doc.test_digit #=> [nil, 2] 
> doc.save
   (0.9ms)  BEGIN
  SQL (1.8ms)  UPDATE "documents" SET "test_digit" = $1, "updated_at" = $2 WHERE "documents"."id" = $3  [["test_digit", "{NULL,2}"], ["updated_at", "2015-02-26 00:32:25.326735"], ["id", 1]]
   (3.7ms)  COMMIT
 => true 
> doc.reload 
  Document Load (1.7ms)  SELECT  "documents".* FROM "documents" WHERE "documents"."id" = $1 LIMIT 1  [["id", 1]]
 => #<Document id: 1, name: "test1", test_digit: [nil, 2], test_string: ["2"], created_at: "2015-02-25 23:51:32", updated_at: "2015-02-26 00:32:25"> 

> doc.test_digit #=> [nil, 2]

我使用了以下迁移:

t.integer :test_digit, array: true, default: []
t.string :test_string, array: true, default: []

Update方法更新数据库,因此您的模型属性不再是脏的。

Good guide on this

  

更新方法似乎也足够聪明,可以删除空字符串。

这不是正常行为,根据pgsql adapter / array_parser的来源,空数组元素应该保存并加载为任何其他值。 (此功能已在Aug 20, 2012上添加到适配器,以防您使用旧版本)