Rails 5用于CSV导出的自定义控制器操作

时间:2018-02-03 21:24:35

标签: ruby-on-rails ruby csv http-status-code-404 controllers

我使用Ruby的内置CSV功能将一些表导出为csv文件。如果我在

,一切正常
def index
// code
end

但是,我在控制器中有一个名为'annual'的自定义操作,带有'respond_to块,如下所示:

respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @surveys }
  format.csv { send_data @surveys.to_csv, filename: "survey-annual-#{Date.today}.csv" }
end

错误是:

"status":404,"error":"Not Found","exception":"#\u003cActiveRecord::RecordNotFound: Couldn't find Survey with 'id'=annual\u003e","traces":{"Application Trace":[{"id":1,"trace":"app/controllers/surveys_controller.rb:34:in `show'"}]

我不相信这是.csv特有的,因为.json会产生同样的错误。我想知道在模型中定义一个方法'.to_csv'是因为Ruby类结构导致问题;我对Ruby不够好,但却找不到答案。

谢谢!

1 个答案:

答案 0 :(得分:0)

它实际上是一个非常基本和常见的路由错误,与CSV生成无关。如果你不相信我,请检查日志。

Rails中的路由按其定义的顺序具有优先级。因此,如果您将路线声明为:

resources :surveys
get 'surveys/annual', to: 'surveys#annual'

surveys/annual的请求将始终传递给SurveysController#show,因为它首先匹配。

路线只是超级动力的正则表达式。因此GET /surveys/:id路由不只是寻找整数ID。

相反,以下内容将匹配:

/surveys/1
/surveys/foo
/surveys/foo%20bar%20baz

但不是/surveys/foo/barPOST /surveys/foo

要正确添加其他休息操作,您应该使用块和collection选项:

resources :surveys do
  get :annual, on: :collection
end

这会按正确顺序添加路线,如下所示:

        Prefix Verb   URI Pattern                 Controller#Action
annual_surveys GET    /surveys/annual(.:format)   surveys#annual
       surveys GET    /surveys(.:format)          surveys#index
               POST   /surveys(.:format)          surveys#create
    new_survey GET    /surveys/new(.:format)      surveys#new
   edit_survey GET    /surveys/:id/edit(.:format) surveys#edit
        survey GET    /surveys/:id(.:format)      surveys#show
               PATCH  /surveys/:id(.:format)      surveys#update
               PUT    /surveys/:id(.:format)      surveys#update
               DELETE /surveys/:id(.:format)      surveys#destroy

请参阅: