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

跟随《Agile Web Development with Rails 5.1》实现图片上传遇路由错误

问题排查与解决方案

首先,咱们先解决你遇到的第一个错误:Routing Error - undefined local variable or method 'applicationController' for main:Object。这个不是路由问题,而是你的控制器类继承写错了——Rails里控制器类名是驼峰式命名,首字母必须大写:

# upload_controller.rb 里的第一行要改成:
class UploadController < ApplicationController
  # ... 其他代码不变
end

把applicationController改成ApplicationController,这个拼写错误会导致Rails无法识别控制器类,进而引发路由相关的报错。


接下来解决路由匹配的问题,结合你的控制器动作,咱们来调整routes.rb的配置:

1. 配置get动作(对应上传表单页面)

你的控制器里用了get动作来显示上传表单(虽然常规RESTful用new,但按书里的写法来),所以路由要对应:

get 'upload/new', to: 'upload#get'

这个写法是对的,但要确保控制器里的get方法存在(你的代码里已经有了)。

2. 配置save动作(处理表单提交)

因为保存数据是POST请求,不能用get,所以要添加POST路由:

post 'upload/save', to: 'upload#save'

这样当表单提交时,Rails才能找到对应的动作处理请求。

3. 配置show和picture动作

这两个动作需要接收id参数,所以路由要包含:id占位符:

get 'upload/show/:id', to: 'upload#show'
get 'upload/picture/:id', to: 'upload#picture'

最终的routes.rb应该是这样:

Rails.application.routes.draw do
  resources :orders
  resources :line_items
  resources :carts
  resources :pictures
  root 'store#index', as: 'store_index'
  resources :products do
    get :who_bought, on: :member
  end

  # 上传相关路由
  get 'upload/new', to: 'upload#get'
  post 'upload/save', to: 'upload#save'
  get 'upload/show/:id', to: 'upload#show'
  get 'upload/picture/:id', to: 'upload#picture'
end

另外,顺便提一下你模型里的一个拼写错误,虽然和路由无关,但会导致上传保存失败:

# model/picture.rb 里的 File.basement 要改成 File.basename
def base_part_of(file_name)
  File.basename(file_name).gsub(/[^|\w._-]/, '')
end

File.basement是不存在的方法,正确的是File.basename。


最后,测试的时候:

  • 访问/upload/new应该能看到上传表单
  • 提交表单后会触发POST /upload/save,成功的话跳转到/upload/show/:id
  • 访问/upload/picture/:id应该能显示图片内容

内容的提问来源于stack exchange,提问作者Simon Cooper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:35:24