如何在JSON中发送字符串数组以在Rails中创建多个对象?

时间:2013-09-11 12:28:23

标签: ruby-on-rails ruby json paperclip

我想通过在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应该是什么样的?

1 个答案:

答案 0 :(得分: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"]

此时,我们拥有与为包含两个ASCII字符串的数组创建的JavaScript相同的基本字符串。对于这部分测试,无论是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。这就是为什么我们将“unwrapped”数组传递给map并让它与元素一起玩。