Rails自定义控制器方法未被调用,路由匹配异常求助
嘿,我一眼就看出两个关键问题,咱们一个个解决:
1. 为什么/entries/fetch_headlines会被路由到show动作?
你当前的路由配置里,get 'fetch_headlines', to: 'entries#fetch_headlines'对应的是根路径下的/fetch_headlines接口,而你请求的是/entries/fetch_headlines——这个路径刚好匹配resources :entries生成的GET /entries/:id规则(Rails直接把fetch_headlines当成了id参数)。
而且就算你把自定义路由改成/entries/fetch_headlines,如果它放在resources :entries后面,Rails还是会优先匹配/:id的规则,因为路由是从上到下按顺序匹配的,先匹配到的规则会生效。
2. 正确配置fetch_headlines路由的两种方式
方式一:显式定义并调整顺序
把自定义路由放在resources :entries之前,指定完整的路径:
# routes.rb get 'entries/fetch_headlines', to: 'entries#fetch_headlines' resources :entries resources :keywords resources :networks
方式二:用RESTful集合路由(更符合Rails最佳实践)
把fetch_headlines作为entries的集合动作,Rails会自动生成正确的路由,还不用操心顺序问题:
# routes.rb resources :entries do get :fetch_headlines, on: :collection end resources :keywords resources :networks
这样生成的路由就是GET /entries/fetch_headlines,完美匹配你的请求。
3. 为什么请求不存在的id不会报错?
默认情况下,Rails的show动作不会主动验证id对应的资源是否存在。你需要在EntriesController的show方法里加个判断:
# app/controllers/entries_controller.rb def show @entry = Entry.find(params[:id]) rescue ActiveRecord::RecordNotFound render plain: "找不到对应的Entry", status: :not_found # 也可以渲染404页面或者重定向,根据需求调整 end
用find方法时,找不到记录会抛出ActiveRecord::RecordNotFound异常,开发环境下默认会显示错误堆栈,生产环境则会返回404页面。
验证路由是否生效
最后记得在终端跑一下rails routes命令,看看生成的路由列表里,fetch_headlines对应的路由是不是排在entries#show前面,这样就能确保请求被正确路由了。
内容的提问来源于stack exchange,提问作者ed_is_my_name

