これに似た質問があることは知っていますが、まだ良い答えは見つかりません。私がする必要があるのは、オブジェクトの説明を私のcreateメソッドの1つに送信することです。これには、:imageと呼ばれるものを含むいくつかの異なる属性が含まれています。
has_attached_file :image
画像をbase64としてエンコードおよびデコードすることにより、画像の送信をJSONで直接実行できることを今読みましたが、それは私にとって汚い解決策のように感じます。もっと良い方法があるはずです。
別の解決策は、multipart/form-dataリクエストを送信することです。これは、 LEEjavaがここで説明するものとよく似ています。 その1つに関する問題は、リクエストパラメータがRails3.2.2、そしてJSON.parseがparamsを解析しようとするとエラーを吐き出します。あるいは、何かを誤解しているRailsかもしれません。
開始済みPOST"/api/v1/somemodel.json?token=ZoipX7yhcGfrWauoGyog" for 127.0.0.1 at 2012-03-18 15:53:30 +0200 Processing by Api :: V1 :: SomeController#create JSONパラメータとして:{"{\ n
\"parentmodel \":{\ n\"superparent_id \":1、\ n
\"説明\":\ "花を楽しむ\"、\ n\"\": "=> {"\n
{\ n\"someattribute \":1、\ n
\"someotherattribute \":2、\ n\"image \":\ "image1 \"\n
}\n "=> {"\n}\n} "=> nil}}、" token "=>" ZoipX7yhcGfrWauoGyog "}
読みづらいです。 JSON.parse(params [:parentmodel])はここでは不可能であり、トークン属性のためにJSON.parse(params)もできません。JSON.parse(params)がこのエラーをスローします。
TypeError(ActiveSupport :: HashWithIndifferentAccessを文字列に変換できません)
これは私がこの問題に完全に間違って取り組んでいるのか、私が何かをしているだけなのかを私に信じさせる。いずれにせよ、私は何かが間違っていると確信することができます。 :)
これを行うより良い方法はありますか?誰かがガイド/チュートリアルを私に指摘したり、これにどのように取り組むべきかを説明した答えを書いたりできますか?
前もって感謝します
UPDATE:そのため、実際には機能していますが、テストのみです。これがどのように機能するかは完全にはわかりませんが、おそらく誰かが私のためにギャップを埋めることができますか?これはテストコードの一部です(画像:fixture_file_upload(...)は重要な部分です)。
parts_of_the_object = { someattribute: 0, someotherattribute: 0, image: fixture_file_upload('/images/plot.jpg', 'image/jpg') }
私のparams []は通常のHTMLフォームが送信されたように見えますが、これは奇妙です(そして素晴らしいです)。
Parameters: {"superparentid"=>"1", "plots"=>[{"someattribute"=>"0", "someotherattribute"=>"0", "image"=>#<ActionDispatch::Http::UploadedFile:0x007f812eab00e8 @original_filename="plot.jpg", @content_type="image/jpg", @headers="Content-Disposition: form-data; name=\"plots[][image]\"; filename=\"plot.jpg\"\r\nContent-Type: image/jpg\r\nContent-Length: 51818\r\n", @tempfile=#<File:/var/folders/45/rcdbb3p50bl2rgjzqp3f0grw0000gn/T/RackMultipart20120318-1242-1cn036o>>}], "token"=>"4L5LszuXQMY6rExfifio"}
リクエストは同様に行われ、ポストリクエストはrspecで行われます。
post "/api/v1/mycontroller.json?token=#{@token}", thefull_object
だから私はそれがすべてうまくいっている。私はそれがどのように正確に機能するのか知りません! RSpecだけでなく、自分でもこのような応答を作成できるようにしたいと考えています。 :-)
昨日、この質問で非常に似たようなことをするのにひどい時間がありました。実際、私は質問を書きました: Android/JavaからRoR CarrierwaveへのBase64アップロード
その結果、コントローラーにアップロードされた画像オブジェクトを作成し、それをparamsに注入しました。
この特定の例では、base64ファイル(JSONは埋め込みファイルをサポートしていないため、そうだと思います)をシステムの一時ファイルとして保存してから、そのUploadedFileオブジェクトを作成し、最終的にそれをパラメータ。
私のjson/paramsは次のようになります:
picture {:user_id => "1", :folder_id => 1, etc., :picture_path {:file => "base64 awesomeness", :original_filename => "my file name", :filename => "my file name"}}
これが私のコントローラーの外観です。
# POST /pictures
# POST /pictures.json
def create
#check if file is within picture_path
if params[:picture][:picture_path]["file"]
picture_path_params = params[:picture][:picture_path]
#create a new tempfile named fileupload
tempfile = Tempfile.new("fileupload")
tempfile.binmode
#get the file and decode it with base64 then write it to the tempfile
tempfile.write(Base64.decode64(picture_path_params["file"]))
#create a new uploaded file
uploaded_file = ActionDispatch::Http::UploadedFile.new(:tempfile => tempfile, :filename => picture_path_params["filename"], :original_filename => picture_path_params["original_filename"])
#replace picture_path with the new uploaded file
params[:picture][:picture_path] = uploaded_file
end
@picture = Picture.new(params[:picture])
respond_to do |format|
if @picture.save
format.html { redirect_to @picture, notice: 'Picture was successfully created.' }
format.json { render json: @picture, status: :created, location: @picture }
else
format.html { render action: "new" }
format.json { render json: @picture.errors, status: :unprocessable_entity }
end
end
end
この時点で残すべきことは、一時ファイルを削除することだけです。これは、tempfile.delete
これがあなたの質問に役立つことを願っています!私は昨日解決策を探すために一日中過ごしました、そして私が見たすべては行き止まりです。ただし、これは私のテストケースでは機能します。
TomJは良い答えを出しましたが、少なくともRails 3/Ruby 1.9にはいくつかの小さな穴があります。
まず、paramsオブジェクトのUploadedFileオブジェクトの可能性があるものに対して[]を呼び出さないでください。たとえば、最初に.is_a?(Hash)
であることを確認してください。
また、書き込み後は必ずtempfile.rewind()
を実行してください。そうしないと、長さが0のファイルが取得されます。
UploadedFileのコンストラクターへのパラメーターの_:original_filename
_キーは不要/未使用です。一方、_:type
_キーを提供することもできます。 typeの値を見つける簡単な方法はmime_type = Mime::Type.lookup_by_extension(File.extname(original_filename)[1..-1]).to_s
です
以下は、変更が適用されたバージョンです。
_# POST /pictures
# POST /pictures.json
def create
#check if file is within picture_path
if params[:picture][:picture_path].is_a?(Hash)
picture_path_params = params[:picture][:picture_path]
#create a new tempfile named fileupload
tempfile = Tempfile.new("fileupload")
tempfile.binmode
#get the file and decode it with base64 then write it to the tempfile
tempfile.write(Base64.decode64(picture_path_params["file"]))
tempfile.rewind()
mime_type = Mime::Type.lookup_by_extension(File.extname(original_filename)[1..-1]).to_s
#create a new uploaded file
uploaded_file = ActionDispatch::Http::UploadedFile.new(
:tempfile => tempfile,
:filename => picture_path_params["filename"],
:type => mime_type)
#replace picture_path with the new uploaded file
params[:picture][:picture_path] = uploaded_file
end
@picture = Picture.new(params[:picture])
respond_to do |format|
if @picture.save
format.html { redirect_to @picture, notice: 'Picture was successfully created.' }
format.json { render json: @picture, status: :created, location: @picture }
else
format.html { render action: "new" }
format.json { render json: @picture.errors, status: :unprocessable_entity }
end
end
_
終わり
キャリアウェーブを使用している場合、この目的のための素晴らしい宝石があります