0

我想通过在 JSON 中发送两个 BASE64 字符串来分配到我的文档的附件,如下所示。

curl -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{"document":{"image_data":["some_base64_string_1", "some_base64_string_2"], "note":"Some note"}}' \
http://myap.dev/api/v1/documents.json

class Document < ActiveRecord::Base
  attr_accessor :image_data

  belongs_to :user
  has_many :attachments

  before_save :decode_image_data

  def decode_image_data
    if self.image_data.present?     
        # here I want to get image_data and create two attachments
        # image_data is right now nil
     end
  end
end

我的 JSON 应该是什么样的?

4

1 回答 1

0

Base64 是一个红鲱鱼(可能会混淆一个论点),所以让我们先把它放在一边。

JSON 能够表示一个数组,所以这是开始的地方,因为你想要两个东西。假装我们正在做 JavaScript 和浏览器会做的事情很容易:

require 'json'

ary = ['content for box one', 'content for box two']
puts JSON[ary]
# >> ["content for box one","content for box two"]

在这一点上,我们拥有了与 JavaScript 为包含两个 ASCII 字符串的数组创建的相同类型的基本字符串。对于这部分测试,无论是 ASCII 还是二进制都无关紧要。

请注意,JSON 将字符串的内容单独留在了数组中。我们可以在这些字符串中使用 BASE64 编码,并且知道 JSON 不会处理它:

puts JSON[ ary.map{ |s| Base64.encode64(s) } ]
# >> ["Y29udGVudCBmb3IgYm94IG9uZQ==\n","Y29udGVudCBmb3IgYm94IHR3bw==\n"]

这显示了在 Rails 中反转流程之前您希望接收的 JSON 字符串。

将其分配给一个变量(就好像它是从浏览器接收的一样)以进行进一步的混乱:

incoming_json = JSON[ary.map{ |s| Base64.encode64(s) } ]
incoming_json
# => "[\"Y29udGVudCBmb3IgYm94IG9uZQ==\\n\",\"Y29udGVudCBmb3IgYm94IHR3bw==\\n\"]"

假装incoming_json是 Rails 接收的 JSON。将它传递JSON[]给解码,它会将传入的字符串返回到一个 BASE64 编码字符串数组中,这就是你传入的内容。从 BASE64 解码这些内容,您将获得一个包含已发送内容的数组:

JSON[incoming_json].map{ |s| Base64.decode64(s) } 
# => ["content for box one", "content for box two"]

这是两个“二进制”流的往返编码和解码。对于 BASE64 来说,它们是 ASCII 文本还是二进制数据流并不重要,JSON 也不在乎,因为它只关心撤消包装器以创建 Ruby 数组。这些数组元素中的内容将与其他内容有关,而不是 JSON。这就是为什么我们将“未包装”数组传递给map并让它与元素一起玩。

于 2013-09-11T14:15:51.983 回答