如何将数组字段序列化为MySQL?

时间:2015-08-10 09:50:18

标签: ruby-on-rails arrays ruby ruby-on-rails-4

我的 request_type 是我数据库中的数组字段。为此,我做了以下迁移

def change
    change_column :users, :request_type, :string, array: true, default: '{}'
end

我是从this question获得的。

我还在模型文件中添加了serialize

class User < ActiveRecord::Base
  belongs_to :client
  serialize :request_type, Array
  self.per_page = 15
end

用户可以执行许多请求,我试图以这种格式存储在他们的记录中:

request_type: {"Discount", "Offer", "other options"}

我也尝试从控制台更新它们,但它也没有在那里工作。

a.request_type.push("offer")

收到NoMethodError: undefined method push' for "[]":String错误。

当我尝试添加项目时

a.request_type << "Offer"

该值变为"[]Offer"

我知道它存储为字符串,所以如何更新此字段?

我使用的是rails 4,ruby 2.2.2,mysql。

修改堆栈跟踪

2.2.2 :016 > a = User.last
  User Load (0.4ms)  SELECT  `users`.* FROM `users`  ORDER BY `users`.`id` DESC LIMIT 1
 => #<User id: 13, name: nil, email: nil, address: nil, mobile_number: "1234567890", client_id: 27, selected_option: nil, created_at: "2015-08-10 09:46:11", updated_at: "2015-08-10 09:46:11", ad_code: "1000014", request_type: "[]", sid: nil, circle: nil> 
2.2.2 :017 > a.request_type << "offer"
 => "[]offer" 
2.2.2 :018 > a.request_type.push("offer")
NoMethodError: undefined method `push' for "[]offer":String
2.2.2 :008 > a.request_type << "offer".to_yaml
 => "[]--- offer\n...\n" 
2.2.2 :011 > a.request_type << "mnb".to_yaml
 => "[]--- offer\n...\n--- mnb\n...\n" 

1 个答案:

答案 0 :(得分:3)

使用MySql的Rails 4将数组序列化为YAML,但您将默认设置为'{}',无法正确反序列化并保持字符串。当我以这种方式测试时,我得到了与你相同的结果。相反,在迁移中,使用default: []并让Rails将列默认设置为适当序列化的YAML版本。

这在Rails 4.0.13,Ruby 2.2.2,MySQL 5.6.13中进行了测试:

class AddThings < ActiveRecord::Migration
  def change
    create_table :things do |t|
      t.string :items, array: true, default: []
    end
  end
end
class Thing < ActiveRecord::Base
  serialize :items
end
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| items | varchar(255) | YES  |     | --- []  |                |
+-------+--------------+------+-----+---------+----------------+
> t = Thing.new
 => #<Thing id: nil, items: []>
> t.items << 'a'
 => ["a"]
> t.save
  SQL (0.3ms)  INSERT INTO `things` (`items`) VALUES ('---\n- a\n')
> t = Thing.last
 => #<Thing id: 1, items: ["a"]>
> t.items = %w[a b c]
 => ["a", "b", "c"]
> t.save
  SQL (0.3ms)  UPDATE `things` SET `items` = '---\n- a\n- b\n- c\n' WHERE `things`.`id` = 1
 => true
> t.reload.items
 => ["a", "b", "c"]