Rails+React项目使用ActiveStorage如何无需序列化器返回所有商品图片URL
问题根源
Product.all返回的是商品集合对象,不是单个商品实例,image是单个Product模型绑定的ActiveStorage附件方法,不能直接在集合上调用,因此会报undefined method 'image'错误- 原有代码中对商品拼接图片URL的map操作没有将处理结果赋值给变量,直接被丢弃,返回的JSON中没有对应字段
后端修改方案(products_controller.rb)
不需要查询全量商品,直接处理分页后的商品列表即可:
# Main Preview def index @products = Product.paginate(page: params[:page], per_page: 3).order(created_at: :desc) # 给每个商品拼接图片URL products_with_image = @products.map do |product| product.as_json.merge( # 先判断图片是否存在,避免调用url_for时报错 image_url: product.image.attached? ? url_for(product.image) : nil ) end render json: { products: products_with_image, page: @products.current_page, pages: @products.total_pages } end
前端修改方案(Product.jsx)
原有代码只存储了单个图片链接,且useEffect依赖错误会触发死循环,修改后直接遍历返回的商品列表取对应图片URL即可:
// 存储商品列表、当前页、总页数 const [products, setProducts] = useState([]) const [currentPage, setCurrentPage] = useState(1) const [totalPages, setTotalPages] = useState(1) // 缺省图地址 const DEFAULT_IMAGE = "https://image.com/1920x1080" useEffect(() => { AOS.init({}); axios .get("/api/v1/products/index", { params: { page: currentPage }, withCredentials: true }) .then((response) => { setProducts(response.data.products); setCurrentPage(response.data.page); setTotalPages(response.data.pages); }) .catch((error) => { console.log("获取商品列表错误", error); }); // 依赖改为页码,切换页码时重新拉取数据 }, [currentPage]); // 渲染商品列表时直接取每个商品的image_url return ( <div className="product-list"> {products.map(product => ( <div key={product.id} className="product-card"> <img src={product.image_url || DEFAULT_IMAGE} alt={product.name} /> <p>{product.name}</p> <span>¥{product.price}</span> </div> ))} </div> )
额外注意点
- 如果Product模型绑定的是多图(配置为
has_many_attached :images),将单图处理逻辑改为遍历生成URL数组即可:image_urls: product.images.attached? ? product.images.map { |img| url_for(img) } : [] - 开发环境下需要配置Rails默认域名端口,避免url_for生成的链接无法访问,在
config/environments/development.rb中添加:Rails.application.routes.default_url_options[:host] = 'localhost' Rails.application.routes.default_url_options[:port] = 3000
内容的提问来源于stack exchange,提问作者Ashkan Ebtekari
相关产品推荐
相关产品推荐

