Экспорт CSV с помощью Mongoid и FasterCSV

#ruby-on-rails #csv

#ruby-on-rails #csv

Вопрос:

 Class UserController
  def export_users
    users = User.all
    stream_csv do |csv|
      csv << ["Name","Email","Gender"]
      users.each do |i|
        csv << [i.name,i.email,i.gender]
      end
    end
  end

def stream_csv
    require 'fastercsv'

        filename = params[:action]   ".csv"

        #this is required if you want this to work with IE      
        if request.env['HTTP_USER_AGENT'] =~ /msie/i
            headers['Pragma'] = 'public'
            headers["Content-type"] = "text/plain"
            headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
            headers['Content-Disposition'] = "attachment; filename="#{filename}""
            headers['Expires'] = "0"
        else
            headers["Content-Type"] ||= 'text/csv'
            headers["Content-Disposition"] = "attachment; filename="#{filename}""
            controller.response.headers["Content-Transfer-Encoding"] = "binary"
        end

        render :text => Proc.new { |response, output|
            csv = FasterCSV.new(output, :row_sep => "rn")
            yield csv
        }
    end
end
  

Ошибка: «#Proc:0x9382539@/sites/app/controllers/export_controller.rb:56 «

Использование Ruby 1.8 и Rails 3.0.9

Итак, я думаю, проблема здесь в том, что я неправильно использую «Proc». Или это не должно действовать как просто еще один блок…

Я думал о программировании новой логики в классе, чтобы она лучше читалась. Но если бы кто-нибудь мог объяснить мне, почему мой код неправильный, или хотя бы указать мне новое направление, то я, возможно, смог бы узнать здесь что-то новое. Спасибо

Примечание: найден лучший способ:

 def export_inverts
  require 'fastercsv'
  inverts = Invert.all
  filename = params[:action]   ".csv"

  #this is required if you want this to work with IE
  if request.env['HTTP_USER_AGENT'] =~ /msie/i
    headers['Pragma'] = 'public'
    headers["Content-type"] = "text/plain"
    headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
    headers['Content-Disposition'] = "attachment; filename="#{filename}""
    headers['Expires'] = "0"
  else
    headers["Content-Type"] ||= 'text/csv'
    headers["Content-Disposition"] = "attachment; filename="#{filename}""
    headers["Content-Transfer-Encoding"] = "binary"
  end

  csv_string = FasterCSV.generate do |csv|
    csv << ["Genus","Species","Common Name","Pet Name","Gender"]
    inverts.each do |i|
      csv << [i.scientific_name,i.scientific_name,i.common_name,i.pet_name,i.gender]
    end
  end
  render :text => csv_string
end
  

Ответ №1:

Yield может использоваться только внутри функции или блока. Yield используется в функции, которая принимает блок, скажем, для ввода некоторого значения в блок. На самом деле там сказано, что это значение передается в процесс, в который блок был преобразован с помощью оператора амперсанда (в большинстве случаев). Однако вы могли бы передать Proc функции, которая ожидала этого.

Здесь вы просто хотите вернуть значение из процедуры, и «yield» не требуется.