2011-11-13 4 views
2
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 => "\r\n") 
      yield csv 
     } 
    end 
end 

Err: "#Proc: [email protected]/sites/app/controllers/export_controller.rb: 56"CSV Exporter avec MongoId et FasterCSV

utilisant Ruby 1.8 et Rails 3.0.9

Alors Je pense que le problème ici est que je n'utilise pas "Proc" droit. Ou ce n'est pas censé agir comme un autre bloc ...

J'ai pensé à programmer une nouvelle logique dans la classe afin de mieux lire. Mais si quelqu'un pouvait m'expliquer pourquoi mon code est faux ou au moins me diriger dans une nouvelle direction que je pourrais être en mesure d'apprendre quelque chose de nouveau ici. Merci

Note: Trouvé une meilleure façon:

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 

Répondre

2

rendement ne peut être utilisé dans une fonction ou d'un bloc. Le rendement est utilisé dans une fonction qui prend un bloc pour dire, donner de la valeur dans le bloc. En fait, il dit céder cette valeur dans le proc que le bloc a été converti en opérateur de l'esperluette (dans la plupart des cas). Cependant, vous pourriez passer un Proc à une fonction qui l'attendait.

Ici, vous voulez juste renvoyer la valeur du proc et "yield" n'est pas nécessaire.