将db导出到csv时如何包含参数?

时间:2014-11-14 17:45:53

标签: ruby-on-rails csv redmine

我正在尝试将一组记录导出到我的Redmine插件中的csv文件中。记录存储在mysql数据库中,该数据库有一列project_id,用于将每条记录绑定到特定项目。我只想导出与project_id的某些值匹配的记录。

应用程序/控制器/ foo_controller.rb:

before_filter :find_project

def index
  @foos = Foo.order(:id).where("project_id = ?", @project.id) # csv request throws NoMethodError here because @project is nil.
  respond_to do |format|
    format.html
    format.csv { send_data @foos.to_csv(:col_sep => ",") }
  end
end

private
def find_project
  if params[:project_id].present?
    @project = Project.find params[:project_id]
  end
end

init.rb

Redmine::Plugin.register :foo_plugin do
  # Some info stuff...
  # Some module/permission stuff...

  menu :project_menu, :foos, {:controller => 'foo_con', :action => 'index'}, :caption => 'Foos', :param => :project_id

end

据我所知,问题在于如何在rails中处理csv请求。首次加载索引页面时,project_id数组中会自动包含params。但是当它重新加载index来处理csv请求时,project_id不会被添加到params数组中。有没有办法改变这种行为?

1 个答案:

答案 0 :(得分:0)

我没有看到任何创建.csv请求的链接。在菜单链接中添加:format => 'csv'

此外,您可能需要send_data中的一些额外信息才能导出。例如:

 format.csv  { send_data(@foos.to_csv, :type => 'text/csv; header=present', :filename => 'issues.csv') }

另一方面,Redmine已为可用的@query内置CSV导出功能。你可以通过做这样的事情来利用:

cond = "project_id IS NULL"
cond << " OR project_id = #{@project.id}" if @project
@query = IssueQuery.where(cond)

respond_to do |format|
    # ...
    format.csv  { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
    # ...

query_to_csv功能位于queries_helper.rb

def query_to_csv(items, query, options={})
    encoding = l(:general_csv_encoding)
    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
    query.available_block_columns.each do |column|
      if options[column.name].present?
        columns << column
      end
    end

    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
      # csv header fields
      csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
      # csv lines
      items.each do |item|
        csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
      end
    end
    export
  end