0

问题就在最后一个代码片段的上方。谢谢你。(环境细节结束)

post_controller.rb

class PostsController < ApplicationController  
def create
    @post = Post.new(params[:post])
    respond_to do |format|
      format.xml { render :xml => @post.to_xml(:include => [ :assets])}
end
end

帖子.rb

class Post < ActiveRecord::Base
  has_many    :assets, :as => :attachable, :dependent => :destroy
end

资产.rb

class Asset < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
  has_attached_file :data,
                    :url  => "/assets/:id",
                    :path =>":rails_root/assets/:id_partition/:style/:basename.:extension"
  def name
    data_file_name
  end

  def content_type
    data_content_type
  end

  def file_size
    data_file_size
  end
  end

现在当我们发布这些信息时

POST /posts.xml HTTP/1.1
Accept-Encoding: gzip,deflate
Accept: application/xml
Content-Type: application/xml
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Content-Length: 60

<post><body>postbody</body><title>post_title</title></post>

一个帖子条目被创建,当我发布这个

POST /posts.xml HTTP/1.1
Content-type: multipart/mixed; boundary=---------------------------7d226f700d0
Accept: application/xml,text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_21
Host: 192.168.0.105:8080
Connection: keep-alive
Content-Length: 1710

-----------------------------7d226f700d0
content-disposition: form-data; name="post[title]"
Content-Length: 10
post_title
-----------------------------7d226f700d0
content-disposition: form-data; name="post[body]"
Content-Length: 8
postbody
-----------------------------7d226f700d0
content-disposition: form-data; name="post[assets_attributes][0][data]"; filename="C:/Users/mv288/files/1.txt"
content-type: application/octet-stream
ÿþ
sample file content
-----------------------------7d226f700d0
content-disposition: form-data; name="post[assets_attributes][0][data]"; filename="C:/Users/mv288/Pictures/1.txt"
content-type: application/octet-stream
ÿþ
sample file content
-----------------------------7d226f700d0

一个带有 2 个文件附件的新帖子被创建。

现在的问题是,我想获得以下 HTTP 帖子(请注意文件附件之前的 xml 部分)来创建一个带有 2 个附件的帖子,而不需要额外的更改(posts_controller 或 routes.rb)。那可能吗?

POST /posts.xml HTTP/1.1
Content-type: multipart/mixed; boundary=---------------------------7d226f700d0
Accept: application/xml,text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_21
Host: 192.168.0.105:8080
Connection: keep-alive
Content-Length: 1710

-----------------------------7d226f700d0
Content-type: application/xml; charset=UTF-8
Content-Length: 59
<post><body>postbody</body><title>post_title</title></post>
-----------------------------7d226f700d0
content-disposition: form-data; name="post[assets_attributes][0][data]"; filename="C:/Users/mv288/files/1.txt"
content-type: application/octet-stream
ÿþ
sample file content
-----------------------------7d226f700d0
content-disposition: form-data; name="post[assets_attributes][0][data]"; filename="C:/Users/mv288/Pictures/1.txt"
content-type: application/octet-stream
ÿþ
sample file content
-----------------------------7d226f700d0Blockquotetest

在 Windows 2007 上使用 jruby 1.5.2/jdk1.6、rails 2.3.4、paperclip-2.3.3 - 64 位

4

1 回答 1

0

至少 rails 2.3.4 不会自动执行此操作。需要编写一个 multipart/related 解析器并在 initializers/mime_types.rb 中注册它

注意:请随意更新副本中的硬编码值(如主要和附件部分前缀等)。

同样的策略也可以用于多部分/相关内容。在下面的示例中,我们仍在争论是否使用 multipart/related 或 multipart/mixed。

Microsoft 关于此主题的说明。 http://msdn.microsoft.com/en-us/library/ms527355(EXCHG.10).aspx

Mime::Type.register "multipart/mixed", :mixed

class ActionController::Request
  def initialize(env)
    Thread.current[:request]=self
    super
  end

end

class MultiPartParamsParser

  def main_part_name
   "main"
  end

  def attachment_part_prefix
    "my_company_attachment"
  end

  def content_type(main_part)
    # TODO ----
    :xml_simple
  end

  def content(main_part)
    # TODO implement this
     if main_part.is_a?(String) 
       main_part.gsub!("Content-Type: application/xml",'') # remove content type if it exists
       main_part.strip! # to remove any trailing or leading whitespaces
     else
      main_part[:tempfile].read
     end
  end

  def request
    Thread.current[:request]
  end

  def parse_formatted_parameters(data)
    multi_parts = Rack::Utils::Multipart.parse_multipart(request.try(:env))
    main_part   = multi_parts[main_part_name]
    data        = content(main_part)
    # TODO return an error if data is not found
    params = case content_type(main_part)
      when :xml_simple, :xml_node
        data.blank? ? {} : Hash.from_xml(data).with_indifferent_access
      when :yaml
        YAML.load(data)
      when :json
        if data.blank?
          {}
        else
          ret = ActiveSupport::JSON.decode(data)
          ret = {:_json => data} unless data.is_a?(Hash)
          ret.with_indifferent_access
        end
      else
        {}
    end
    process_attachments(params, multi_parts)
    params                 
  end

  def process_attachments(data, multi_parts)
    data.each do |key, value|
      value ||= key # when array value is nil
      if value.is_a?(Hash) or value.is_a?(Array)
        process_attachments(value, multi_parts)
      elsif value.respond_to?(:match) and value.match("^#{attachment_part_prefix}") and (attachment=multi_parts[value]) # there could Time,Numbers etc.., but we match only string.
        data[key] = create_uploaded_file(attachment) # TODO handle the scenarios for short strings
      end 
    end         
  end

  def create_uploaded_file (attachment)
    upload = attachment[:tempfile]
    upload.extend(ActionController::UploadedFile)
    upload.original_path = attachment[:filename]
    upload.content_type = attachment[:type]
    upload
  end
end

proc = Proc.new do |data|
  MultiPartParamsParser.new.parse_formatted_parameters(data)
end

ActionController::Base.param_parsers[Mime::Type.lookup('multipart/mixed')] = proc

然后,您可以像这样发布您的消息。嵌套会自动进行,无需对模型或控制器进行进一步更改。

POST /posts.xml HTTP/1.1
Content-type: multipart/mixed; boundary=---------------------------###987612345###
Accept: application/xml,text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Cache-Control: no-cache
Pragma: no-cache
Connection: keep-alive
Content-Length: ##

-----------------------------###987612345###
content-disposition: name="main"
Content-Length: ##
<post><title>post_title</title><body>post_body</body>
    <assets_attributes type="array">
            <asset><data>my_company_attachment_0</data> </asset>
            <asset><data>my_company_attachment_1</data> </asset>
    </assets_attributes>
</post>
-----------------------------###987612345###
content-disposition: name="my_company_attachment_0"; filename="C:/Users/mv288/files/1.txt"
content-type: application/octet-stream
ÿþ
sample file content
-----------------------------###987612345###
content-disposition: name="my_company_attachment_1"; filename="C:/Users/mv288/Pictures/1.png"
content-type: image/png
ÿþ
sample file content
-----------------------------###987612345###
于 2010-10-07T23:25:18.003 回答