Rails 3:如何在没有模板文件的情况下respond_with csv?
我有一个具有 to_csv
方法的对象,我想将其传递给 respond_with
以从我的控制器渲染 csv。我的代码如下所示:
class Admin::ReportsController < AdminController
respond_to :csv
def trips
respond_with TripReport.new
end
end
TripReport 的实例有一个 to_csv 方法。
当我向该操作发出请求时,出现以下错误:
ActionView::MissingTemplate (Missing template admin/reports/trips with {:formats=>[:csv], :handlers=>[:erb, :builder, :rjs, :rhtml, :rxml], :locale=>[:en, :en]} in view paths
所以看起来控制器正在寻找要渲染的模板文件。我该如何解决这个问题?
我希望 csv 格式以与 json 类似的方式响应,因此它在对象上调用 to_csv
并仅渲染输出,这可能吗?
I have an object that has a to_csv
method and I want to pass it to respond_with
to render csv from my controller. My code looks like this:
class Admin::ReportsController < AdminController
respond_to :csv
def trips
respond_with TripReport.new
end
end
Instances of TripReport have a to_csv method.
When I make a request to that action I get the following error:
ActionView::MissingTemplate (Missing template admin/reports/trips with {:formats=>[:csv], :handlers=>[:erb, :builder, :rjs, :rhtml, :rxml], :locale=>[:en, :en]} in view paths
So it looks like the controller is looking for a template file to render. How can I get around this?
I'd rather the csv format responded in a similar way to json, so it calls to_csv
on the object and just renders the output, is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我一直在努力解决同样的问题。我可能找到了解决办法。
我在阅读 :json 和 :xml 的 Renderers.add 源代码时发现了一些线索(链接适用于 Rails 3.0.10 代码,3.1 可能已经有一些更改):
https://github.com/rails/rails/blob/ v3.0.10/actionpack/lib/action_controller/metal/renderers.rb
首先,在模型定义中添加一个简单的
as_csv
方法:这可以是任何内容,只需确保返回一个哈希值即可带有键/值对。哈希比数组效果更好,因为使用键您可以稍后向 CSV 输出添加标题行。
as_csv
的想法来自 Rails 的as_json
方法,该方法返回一个 Ruby 对象,to_json
使用该对象生成实际的 JSON(文本)输出。使用
as_csv
方法后,将以下代码放入应用内config/initializers
的文件中(将其命名为csv_renderer.rb
,例如示例):最后,向控制器代码添加 CSV 支持:
初始化程序代码主要基于 Rails 源代码中的 :json 和 :xml 行为(请参阅上面的链接)。
目前,传递给块的
options
哈希值不会传递给to_csv
调用,因为 CSV 对于允许发送的选项非常挑剔。 Rails 本身添加了一些默认选项(例如 :template 和其他一些选项),这会在将它们传递给to_csv
时出现错误。当然,您可以通过将您自己喜欢的 CSV 选项添加到初始值设定项来更改默认的 CSV 呈现行为。希望这有帮助!
I've been struggling with the exact same problem. I might have found a solution.
I found some clues while reading the Renderers.add source code for :json and :xml (link is for Rails 3.0.10 code, 3.1 might have some changes already):
https://github.com/rails/rails/blob/v3.0.10/actionpack/lib/action_controller/metal/renderers.rb
First, add a simple
as_csv
method to your model definition:This can be anything, just make sure to return a hash with key/value pairs. A Hash works better than an Array, as with keys you're able to add a header row to the CSV output later on. The idea for
as_csv
comes from Rails'as_json
method, which return a Ruby object that is used byto_json
to generate the actual JSON (text) output.With the
as_csv
method in place, put the following code in a file inconfig/initializers
inside your app (name itcsv_renderer.rb
, for example):And finally, add CSV support to your controller code:
The initializer code is largely based on the :json and :xml behaviour from the Rails source code (see link above).
Currently, the
options
hash passed to the block doesn't get passed to theto_csv
call, as CSV is quite picky on which options it allows to be sent. Rails adds some default options by itself (like :template and some others), which gives you an error when passing them toto_csv
. You can change the default CSV rendering behaviour by adding your own preferred CSV options to the initializer, of course.Hope this helps!
这是一个老问题,但这里有一个针对较新版本的 Rails(当前使用 3.2.11 和 Ruby 1.9.3)的自定义渲染器的更新方法,取自 ActionController::Renderers 文档: http://api.rubyonrails.org/classes/ActionController/Renderers.html#method-c-add< /a>
正如 florish 所说,创建一个初始化程序,但添加以下代码:
并按如下方式使用它:
我对上面的代码没有任何功劳,它直接来自文档,但这在 Rails 3.2.11 中对我有用,所以指出它对于第一次遇到这个线程的人。
在我的项目中,我没有使用 to_csv 方法,实际上我首先手动构建 CSV。所以我的代码是这样的:
显然,您应该将 CSV 创建代码移动到其他类或模型,但将其内联放在此处只是为了说明。
This is an old question but here's an updated method for the custom Renderer for newer versions of Rails (currently using 3.2.11 and Ruby 1.9.3) taken from the ActionController::Renderers documentation: http://api.rubyonrails.org/classes/ActionController/Renderers.html#method-c-add
As florish said, create an initializer but add this code:
And use it as such:
I take no credit for the code above, it's straight from the documentation, but this worked for me in Rails 3.2.11 so pointing it out for people coming across this thread for the first time.
In my project I'm not using a to_csv method, I'm actually building the CSV manually first. So here's what mine looks like:
You should obvious move the CSV creation code to some other class or model but putting it here inline just to illustrate.
我认为您的模型必须有一个
to_csv
方法,以 csv 形式返回属性。之后,如果 Rails 不隐式调用
to_csv
方法,我会尝试I think your model would have to have a
to_csv
method that returns the attributes as csv.After that, if Rails doesn't call the
to_csv
method implicitly, I would try首先在 config/initializers/csv_renderer.rb 中为 CSV mime 类型创建渲染器
,然后向模型添加 to_csv 方法。如果您的数据是数组或哈希,您可能会考虑使用自己的 to_csv 和 to_json 方法为该集合创建一个新类,而不是将所有内容都放在控制器中。如果它是 ActiveRecord 模型,您可以在初始化程序中使用以下内容:
然后您可以将 ActiveRecord 关系传递给 respond_with:
First create a renderer for the CSV mime type in
config/initializers/csv_renderer.rb
Then add a
to_csv
method to your model. If your data is an array or hash you might consider creating a new class for that collection with its own to_csv and to_json methods, instead of having everything in the controller. If its an ActiveRecord model you can use the following in an initializer:You can then pass an ActiveRecord relation to respond_with:
我猜我遇到了与您遇到的类似问题,奥利弗。我意识到在我的路由文件中我使用的是
resource
而不是resources
。我不知道您的 Admin::ReportsController 类中是否有其他操作,也不知道您的路由文件是什么样子,但如果 Reports 具有标准 REST 操作,这就是我解决问题的方法。如果这不适用,请运行
rake paths
以查看您的路由配置是否正确。I ran into what I would guess is a similar problem to what you were experiencing, Oliver. I realized that in my routes file I was using
resource
instead ofresources
. I do not know if you have other actions in your Admin::ReportsController class or what your routes file looks like, but this is how I would tackle the problem if Reports has the standard REST actions.If that does not apply, run
rake routes
to see if your routes are configured correctly.可能的解决方案之一是使用您想要的所有数据实现另一个视图。
One of the possible solutions is to implement another view with all data you want.