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

sk1*_*712 1 ruby arrays ruby-on-rails ruby-on-rails-4

我的数据库中有request_type作为数组字段。为此我在迁移后做了

def change
    change_column :users, :request_type, :string, array: true, default: '{}'
end
Run Code Online (Sandbox Code Playgroud)

我从这个问题得到的。

我还添加serialize到模型文件中。

class User < ActiveRecord::Base
  belongs_to :client
  serialize :request_type, Array
  self.per_page = 15
end
Run Code Online (Sandbox Code Playgroud)

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

request_type: {"Discount", "Offer", "other options"}
Run Code Online (Sandbox Code Playgroud)

我也尝试从控制台更新它们,但它也不起作用。

a.request_type.push("offer")
Run Code Online (Sandbox Code Playgroud)

出现NoMethodError: undefined method push' for "[]":String错误。

当我尝试添加项目时

a.request_type << "Offer"
Run Code Online (Sandbox Code Playgroud)

该值变为"[]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" 
Run Code Online (Sandbox Code Playgroud)

Kri*_*ján 5

Rails 4 with MySql 将数组序列化为 YAML,但您已将默认值设置为 be '{}',它无法正确反序列化并保留为字符串。当我这样测试时,我得到了与你相同的结果。相反,在迁移中,使用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
Run Code Online (Sandbox Code Playgroud)
class Thing < ActiveRecord::Base
  serialize :items
end
Run Code Online (Sandbox Code Playgroud)
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| items | varchar(255) | YES  |     | --- []  |                |
+-------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
> 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"]
Run Code Online (Sandbox Code Playgroud)