Trong Ruby on Rails, một mô hình với trường mảng được tuần tự hóa sẽ không cập nhật trên .save()
nếu mảng trống, nơi mà trước đó nó có dữ liệu.Không thể lưu mảng trống vào cơ sở dữ liệu khi được tuần tự
Tôi đang sử dụng:
- của Ruby 2.2.1
- Rails 4.2.1
sqlite3 1.3.10
Tôi tạo ra một mô hình mới với một lĩnh vực thiết lập dưới dạng văn bản:
đường ray g model Tên người dùng: chuỗi ví dụ: văn bản
Trong tập tin User.rb Tôi nói thêm:
serialize :example, Array
tôi instantiated một trường hợp mới của lớp User:
test = User.new
<User id: nil, name: nil, example: [], created_at: nil, updated_at: nil>
Sau đó, tôi tiết kiệm cho người sử dụng để đảm bảo nó tiết kiệm một cách chính xác:
test.save()
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2015-05-27 16:17:31.902342"], ["updated_at", "2015-05-27 16:17:31.902342"]]
(0.7ms) commit transaction
=> true
Và thêm một số dữ liệu để cảm thấy vui vẻ và có mục đích:
test.example.push(1)
test.example.push(2)
Và lưu nó lên:
test.save()
(0.1ms) begin transaction
SQL (0.3ms) UPDATE "users" SET "example" = ?, "updated_at" = ? WHERE "users"."id" = ? [["example", "---\n- 1\n- 2\n"], ["updated_at", "2015-05-27 16:17:50.331777"], ["id", 1]]
(0.8ms) commit transaction
=> true
Và chắc chắn mọi thứ được lưu độc đáo:
test
<User id: 1, name: nil, example: [1, 2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:17:50">
Tôi đã xóa một mục, xác minh nó đã bị xóa, và lưu nó, làm cho chắc chắn rằng SQL đầu ra hiển thị UPDATE:
test.example.delete(1)
=> 1
test
<User id: 1, name: nil, example: [2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:17:50">
test.save()
(0.1ms) begin transaction
SQL (0.9ms) UPDATE "users" SET "example" = ?, "updated_at" = ? WHERE "users"."id" = ? [["example", "---\n- 2\n"], ["updated_at", "2015-05-27 16:18:30.148553"], ["id", 1]]
(8.9ms) commit transaction
=> true
Tôi đã xóa phần dữ liệu cuối cùng khỏi rray, mảng trống đã được xác minh và lưu nó. Lưu ý việc thiếu hành động UPDATE và trả về đúng:
test.example.delete(2)
=> 2
test
<User id: 1, name: nil, example: [], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:18:30">
test.save()
(0.1ms) begin transaction
(0.1ms) commit transaction
=> true
Nhiều lần lưu có cùng kết quả. Một đối tượng tài khoản mới vẫn có mảnh cuối cùng của dữ liệu trong nó:
test = User.find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
<User id: 1, name: nil, example: [2], created_at: "2015-05-27 16:17:31", updated_at: "2015-05-27 16:18:30">
Một cách giải quyết là loại bỏ những "mảng" từ dòng serialize trong mô hình khởi sân khi nil. Nhưng điều này có nghĩa là lần đầu tiên tôi thêm dữ liệu vào một cá thể mới, tôi phải đặt trường theo cách thủ công thành một mảng trống (test.example = []
) để gọi .push()
trên đó. Tất cả mọi thứ hoạt động tốt trong thiết lập này, và mảng mới làm trống tiết kiệm hạnh phúc cho DB.
tôi thấy một vấn đề khép kín trên Rails Github chỉ ra rằng cột serialized luôn nên được lưu, nhưng không có ý tưởng nếu điều này là thích hợp:
https://github.com/rails/rails/issues/8328
tôi không thể phân biệt bất cứ điều gì từ mã nguồn serialize mà có thể thắp sáng cho tôi:
http://apidock.com/rails/ActiveModel/Serializers/Xml/Serializer/serialize
tại sao thêm "mảng" ở cuối dòng nguyên nhân sắp đặt từng mảng trống để không được lưu vào cơ sở dữ liệu ?
Chào mừng bạn đến với Stack Overflow. Dưới đây là một số mẹo để viết câu hỏi: Đừng tack on "Ruby on Rails" hoặc các thẻ tương tự. Stack Overflow (và công cụ tìm kiếm) sử dụng các thẻ bạn đã xác định cho câu hỏi. Thay vào đó chỉ cần viết một câu mô tả ngắn. Trong cơ thể, không cần sử dụng các tiêu đề. Thay vào đó, viết bình thường, như bạn sẽ làm khi viết cho một đồng nghiệp. Stack Overflow giống như một bách khoa toàn thư về lập trình Q & A nhưng với một phong cách ít chính thức hơn. Mô phỏng phong cách của các câu hỏi khác để duy trì giao diện chung. Cũng tìm hiểu định dạng mã nội tuyến. –
Cảm ơn lời khuyên và chỉnh sửa! Tôi sẽ lưu ý lời khuyên này cho các yêu cầu trong tương lai. Bạn có thể xây dựng trên định dạng mã nội tuyến không? Tôi đã sử dụng giao diện điều khiển đầu ra cho bài viết của tôi bởi vì tôi nghĩ rằng nó tốt nhất giới thiệu vấn đề. – hsidar