跟随《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
相关产品推荐
相关产品推荐

