2010-03-18 2 views
11

Я читал подобные вопросы, но многие ответы устарели или недостаточно ясны для меня.Сгенерировать CSV-файл с рельсов

Я хотел бы иметь возможность просто сделать что-то подобное (в действии контроллера):

respond_to do |format| 
    format.html 
    format.csv 
end 

Я знаю, что я бы тогда нужен вид, такие как action.csv.erb


Итак, мои вопросы:

1) Что мне нужно для настройки в рельсах, чтобы это произошло в общем случае.

2) Как настроить представление CSV для отображения некоторых базовых полей из модели?

UPDATE:

Так я пытался идти по пути запятой, я установил и vendored камень.

Тогда согласно прочитанному меня, я бросил это в мою модель (настроить для моих потребностей):

comma do 

user_id 'User' 
created_at 'Date' 
name 'Name' 
end 

Затем я бросил это в контроле за действия индекса (по риому):

format.csv { render :csv => MyModel.limited(50) } 

Тогда при доступе к индексу (не в формате CSV) я получаю следующее сообщение об ошибке ActionController Исключение:

undefined method `comma' for

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

После этого, я освежил (мой локальный индекс страницы), и ошибка изменен:

no such file to load -- comma

Так что на данный момент я решил, что не должен находить файлы запятая, очевидно. Поэтому я скопировал файлы из папки с запятыми из каталога commam, из папки lib в папке, в папку rails lib. Затем я обновил страницу и приземлился на эту ошибку:

uninitialized constant Error

Тогда я в значительной степени сдался.

The errors from the trace were:

/Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:443:in load_missing_constant' /Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:80:in const_missing' /Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:92:in `const_missing'

Другие примечания, я уже установил FasterCSV

Надежда то будет достаточно информации :)

ответ

11

Я предлагаю взглянуть на comma. Он работает очень хорошо и позволяет обрабатывать вещи на уровне модели, в отличие от уровня представления.

+0

Я пробовал это без успеха. – Elliot

+0

Что не сработало для вас? Если вы получаете сообщение об ошибке, можете ли вы обновить исходное сообщение с этой ошибкой? – theIV

+0

Обновлено с ошибкой – Elliot

6

Посмотрите на FasterCSV.

csv_string = FasterCSV.generate do |csv| 

    cols = ["column one", "column two", "column three"] 

    csv << cols 

    @entries.each do |entry|     
    csv << [entry.column_one, entry.column_two, entry.column_three ] 
    end 

    filename = "data-#{Time.now.to_date.to_s}.csv"  

end 

send_data(csv_string, :type => 'text/csv; charset=utf-8; header=present', :filename => filename) 
+0

Значит, это пошло бы в контроллер? И как будет доступ к файлу? – Elliot

+0

Метод send_data возвращает файл для загрузки пользователем. –

+1

Вам нужно поместить бит send_data за пределы генерирующего блока. Также теперь, когда FasterCSV включен в рельсы, вы просто создаете CSV.generate. – jacklin

3

Это ужасно, но CSV-библиотека (в 1.9, == FasterCSV) не будет играть хорошо с meta_where, так что я сделал это так:

@customers.collect {|c| lines.push ["#{c.lastname}","#{c.firstname}","#{c.id}","#{c.type}"} 
lines = lines.collect {|line| line.join(',')} 
csv_string = lines.join("\n") 
respond_to do |format| 
    format.html 
    format.csv { send_data(csv_string, :filename => "#{@plan.name.camelize}.csv", :type => "text/csv") } 
end 

Это некрасиво, но эффективно.

+1

Мне нравится этот ответ, простой и эффективный, если вы просто создаете очень простой CSV (хотя я перевел логику на модель вместо того, чтобы иметь ее в контроллере). –

+0

Да, это был быстрый и грязный хак для меня, но если вы собираетесь использовать его «по-настоящему», то модель намного лучше для него. –

+0

Как раз на стороне примечания, если вы думаете семантически - модель является ужасным местом для этого. Клиент не должен знать, как себя вести. Это просто нелогично, ведь жирные модели слишком заметны в рельсах. Почему бы не сделать PORO, который принимает модель и позволяет этот метод вместо этого? – jQwierdy

Смежные вопросы