You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Faraday上传图片至含Active Storage的Author模型?

问题:Active Storage 图片无法通过Faraday请求保存

相关代码

Author模型

class Author < ApplicationRecord
  has_one_attached :image
end

Faraday连接配置

conn = Faraday.new(
  url: 'http://localhost:3000/',
  headers: {'Content-Type' => 'application/json','Authorization' => "Bearer qAJiTqIJRou0"}
) do |f|
  f.request :multipart
  f.adapter :net_http
end

参数允许设置

def author_params
  params.require(:author).permit(:image, :title, :full_name)
end

发送POST请求的代码

require 'faraday'
require 'faraday/multipart'

payload = { author: {title: "lo"} }
payload[:author][:image] = Faraday::Multipart::FilePart.new(Rails.root.join('app', 'assets', 'images', 'about.jpg'), 'image/jpeg')

conn.post('/api/v1/authors', payload.to_json)

错误提示

Unpermitted parameter: :image. Context: { controller: Api::V1::AuthorsController, action: create, request: #<ActionDispatch::Request:0x00007f85583d7860>, params: {"author"=>{"title"=>"foo iiiiiii", "full_name"=>"tony", "image"=>{"content_type"=>"image/jpeg", "original_filename"=>"about.jpg", "local_path"=>"/home/kashif/ticket_plot_api/app/assets/images/about.jpg", "io"=>"#<File:0x00007f78f416abd8>", "opts"=>{}}}, "controller"=>"api/v1/authors", "action"=>"create"} }

问题原因及修复方案

核心问题在于multipart文件上传请求不能以JSON格式发送,代码存在两个冲突点:

  1. 手动设置Content-Type: application/json请求头,与multipart上传的要求矛盾
  2. 将包含FilePart的payload转为JSON字符串发送,导致后端收到的是哈希结构的image参数,而非Active Storage需要的文件对象

修改步骤:

  1. 移除JSON请求头:Faraday的multipart中间件会自动设置正确的Content-Type: multipart/form-data头,无需手动指定application/json
  2. 直接传递payload哈希:不要调用to_json,让Faraday处理multipart表单的编码逻辑

修改后的代码

Faraday连接配置

conn = Faraday.new(
  url: 'http://localhost:3000/',
  headers: {'Authorization' => "Bearer qAJiTqIJRou0"}
) do |f|
  f.request :multipart
  f.adapter :net_http
end

发送请求代码

require 'faraday'
require 'faraday/multipart'

payload = { author: {title: "lo"} }
payload[:author][:image] = Faraday::Multipart::FilePart.new(Rails.root.join('app', 'assets', 'images', 'about.jpg'), 'image/jpeg')

# 直接传递payload,不要转成JSON
conn.post('/api/v1/authors', payload)

修改后,后端会正确识别image为文件对象,参数允许设置生效,Active Storage即可正常关联图片。

内容的提问来源于stack exchange,提问作者Muhammad Kashif Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:44:52