Rails用simple_forms和ActiveStorage上传商品图片时控制器报错如何解决
问题排查与修复方案
1 错误:The action 'update' could not be found for ProductsController 原因与修复
- 控制器语法错误:你的
create方法末尾多了一个多余的end,导致update方法被定义在ProductsController类的外部,路由无法匹配到对应动作。 - 编辑页表单参数错误:
simple_form_for第一个参数需要接收模型实例@product,你直接传路由地址edit_product_path会导致表单提交的路径、请求方法都不符合Rails路由约定。
2 错误:{"seller":["must exist"]} 原因与修复
- 你的
Product模型大概率配置了belongs_to :seller关联,Rails 5+版本中belongs_to关联默认要求关联对象必须存在,你在create方法中直接调用Product.create()没有传入任何参数,也没有关联当前登录的卖家账号,触发了必填校验。 - 额外问题:你的强参数配置没有放行
picture字段,表单提交的图片数据会被过滤,无法正常完成上传;update方法写法错误,不能直接对Product类调用update方法,需要先查询到对应商品实例再执行更新。
修复后的代码示例
修正后 products_controller.rb
# 注意删除create方法多余的end,保证update方法在控制器类内部 def create # 关联当前登录的卖家,如果你用Devise做身份验证,对应的方法为current_seller @product = current_seller.products.new(product_params) if @product.save redirect_to @product, notice: '商品创建成功' # 若需要返回JSON可替换为下面的写法 # render :show, status: :created, location: @product else render json: @product.errors, status: :unprocessable_entity end end def update # 先查询对应商品实例再更新 @product = Product.find(params[:id]) if @product.update(product_params) redirect_to @product, notice: '商品更新成功' # 若需要返回JSON可替换为下面的写法 # render :show, status: :ok, location: @product else render json: @product.errors, status: :unprocessable_entity end end def product_params # 增加picture参数放行 params.require(:product).permit(:title, :description, :price, :buyer_id, :seller_id, :category, :image_url, :picture) end
修正后 edit.html.erb
<%= simple_form_for @product do |f| %> <h1 class="heading">Edit Product</h1> <%= render 'form', product: @product, f: f %> <% end %>
提示:新建商品页的表单也可以直接用
simple_form_for @product写法,simple_form会自动识别是新建还是编辑场景,生成对应提交路径,不需要额外指定url参数。
内容的提问来源于stack exchange,提问作者Sneha Bhamra
相关产品推荐
相关产品推荐

