csv_rails 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  CsvRails provides a simple way of download csv in Rails 3.
4
4
 
5
+ == Supported versions
6
+ Ruby 1.9 (1.8 not supported)
7
+ Rails 3
8
+ ActiveRecord or Mongoid
9
+
5
10
  == Install
6
11
 
7
12
  To use CsvRails simply add the line
@@ -0,0 +1,44 @@
1
+ require 'csv'
2
+ module CsvRails
3
+ module ActiveModel
4
+ module ClassMethods
5
+ def to_csv(opts={})
6
+ fields = opts[:fields] || csv_fields
7
+ header = csv_header(fields, opts.delete(:i18n_scope))
8
+ all.to_a.to_csv(opts.update(:fields => fields, :header => header))
9
+ end
10
+
11
+ def csv_header(fields, scope=nil)
12
+ fields.map{|f|
13
+ if scope
14
+ I18n.t("#{scope}.#{f}", :default => human_attribute_name(f))
15
+ else
16
+ human_attribute_name(f)
17
+ end
18
+ }
19
+ end
20
+
21
+ def csv_fields
22
+ if self.is_a?(::ActiveRecord::Relation)
23
+ @klass.attribute_names
24
+ else
25
+ attribute_names
26
+ end
27
+ end
28
+ end
29
+
30
+ module InstanceMethods
31
+ def to_csv_ary(fields=nil, opts={})
32
+ fields = attribute_names unless fields
33
+ fields.map{|field|
34
+ field.to_s.split(".").inject(self){|object, f|
35
+ next unless object
36
+ convert_method = "#{f}_as_csv"
37
+ method = object.respond_to?(convert_method) ? convert_method : f
38
+ object.send(method)
39
+ }
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,48 +1,17 @@
1
- require 'csv'
2
1
  module CsvRails
3
2
  module ActiveRecord
4
3
  def self.included(base)
5
- base.extend ClassMethods
6
- ::ActiveRecord::Relation.send(:include, ClassMethods)
7
- base.send(:include, InstanceMethods)
8
- end
9
-
10
- module ClassMethods
11
- def to_csv(opts={})
12
- fields = opts[:fields] || csv_fields
13
- scope = opts.delete(:i18n_scope)
14
- header = fields.map{|f|
15
- if scope
16
- I18n.t("#{scope}.#{f}", :default => human_attribute_name(f))
17
- else
18
- human_attribute_name(f)
19
- end
20
- }
21
- all.to_csv(opts.update(:fields => fields, :header => header))
22
- end
23
-
24
- def csv_fields
25
- if respond_to?(:attribute_names)
26
- attribute_names
27
- elsif self.is_a?(::ActiveRecord::Relation)
28
- @klass.new.attribute_names
29
- else
30
- new.attribute_names
31
- end
4
+ base.extend(CsvRails::ActiveModel::ClassMethods)
5
+ base.send(:include, CsvRails::ActiveModel::InstanceMethods)
6
+ ::ActiveRecord::Relation.send(:include, CsvRails::ActiveModel::ClassMethods)
7
+ unless base.respond_to?(:attribute_names)
8
+ base.extend(ClassMethods) # for rails 3.0.12
32
9
  end
33
10
  end
34
11
 
35
- module InstanceMethods
36
- def to_csv_ary(fields=nil, opts={})
37
- fields = attribute_names unless fields
38
- fields.map{|field|
39
- field.to_s.split(".").inject(self){|object, f|
40
- next unless object
41
- convert_method = "#{f}_as_csv"
42
- method = object.respond_to?(convert_method) ? convert_method : f
43
- object.send(method)
44
- }
45
- }
12
+ module ClassMethods
13
+ def attribute_names
14
+ column_names.map(&:to_sym)
46
15
  end
47
16
  end
48
17
  end
@@ -3,38 +3,43 @@ module CsvRails
3
3
  module Array
4
4
  def self.included(base)
5
5
  base.send(:remove_method, :to_csv)
6
- base.send(:include, CsvRails::Array::InstanceMethods)
7
6
  end
8
7
 
9
- module InstanceMethods
10
- # ==== Options
11
- # * <tt>:fields</tt> - target field names
12
- # * <tt>:header</tt> - header
13
- # * <tt>:without_header</tt> - total_count
14
- # * <tt>:encoding</tt> - encoding
15
- # * <tt>:i18n_scope</tt> - i18n scope
16
- def to_csv(opts={})
17
- fields = opts[:fields]
18
- header = if opts[:header]
19
- opts.delete(:header)
20
- elsif (klass = first.class).respond_to?(:csv_fields)
21
- klass.csv_fields
22
- else
23
- scopes = ['csv_rails']
24
- scopes << opts[:i18n_scope] if opts[:i18n_scope]
25
- fields.map{|f|
26
- defaults = scopes.map{|s| "#{s}.#{f}".to_sym }.push(f.to_s)
27
- I18n.t(defaults.shift, :default => defaults)
28
- } if fields
29
- end
30
- csv = CSV.generate do |_csv|
31
- _csv << header if header && !opts[:without_header]
32
- each do |element|
33
- _csv << element.to_csv_ary(fields, opts)
34
- end
8
+ # ==== Options
9
+ # * <tt>:fields</tt> - target field names
10
+ # * <tt>:header</tt> - header
11
+ # * <tt>:without_header</tt> - total_count
12
+ # * <tt>:encoding</tt> - encoding
13
+ # * <tt>:i18n_scope</tt> - i18n scope
14
+ def to_csv(opts={})
15
+ klass = first.class
16
+ fields = if opts[:fields]
17
+ opts.delete(:fields)
18
+ elsif klass.respond_to?(:csv_fields)
19
+ klass.csv_fields
20
+ else
21
+ []
22
+ end
23
+
24
+ header = if opts[:header]
25
+ opts.delete(:header)
26
+ elsif klass.respond_to?(:csv_header)
27
+ klass.csv_header(fields, opts.delete(:i18n_scope))
28
+ else
29
+ scopes = ['csv_rails']
30
+ scopes << opts[:i18n_scope] if opts[:i18n_scope]
31
+ fields.map{|f|
32
+ defaults = scopes.map{|s| "#{s}.#{f}".to_sym }.push(f.to_s)
33
+ I18n.t(defaults.shift, :default => defaults)
34
+ }
35
+ end
36
+ csv = CSV.generate do |_csv|
37
+ _csv << header if header && !opts[:without_header]
38
+ each do |element|
39
+ _csv << element.to_csv_ary(fields, opts)
35
40
  end
36
- opts[:encoding] ? csv.encode(opts[:encoding]) : csv
37
41
  end
42
+ opts[:encoding] ? csv.encode(opts[:encoding]) : csv
38
43
  end
39
44
  end
40
45
  end
@@ -0,0 +1,17 @@
1
+ module CsvRails
2
+ module Mongoid
3
+ def self.included(base)
4
+ base.send(:include, CsvRails::ActiveModel::InstanceMethods)
5
+ base.const_get(:ClassMethods).tap{|klass|
6
+ klass.send(:include, CsvRails::ActiveModel::ClassMethods)
7
+ klass.send(:include, ClassMethods)
8
+ }
9
+ end
10
+
11
+ module ClassMethods
12
+ def attribute_names
13
+ fields.keys.map(&:to_sym)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module CsvRails
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/csv_rails.rb CHANGED
@@ -1,9 +1,18 @@
1
1
  require 'csv_rails/array'
2
- require 'csv_rails/active_record'
2
+ require 'csv_rails/active_model'
3
3
 
4
- ActiveRecord::Base.send(:include, CsvRails::ActiveRecord)
5
4
  Array.send(:include, CsvRails::Array)
6
5
 
6
+ if defined?(ActiveRecord)
7
+ require 'csv_rails/active_record'
8
+ ActiveRecord::Base.send(:include, CsvRails::ActiveRecord)
9
+ end
10
+
11
+ if defined?(Mongoid)
12
+ require 'csv_rails/mongoid'
13
+ Mongoid::Document.send(:include, CsvRails::Mongoid)
14
+ end
15
+
7
16
  ActionController::Renderers.add :csv do |obj, options|
8
17
  filename = options[:filename] || File.basename(request.path)
9
18
  send_data obj.to_csv(options), :type => Mime::CSV,
@@ -85,8 +85,8 @@ class CsvRails::ActiveRecordTest < ActiveSupport::TestCase
85
85
 
86
86
  test ".to_csv with i18n option" do
87
87
  I18n.locale = :ja
88
- translated = [:id, :name].map{|f| I18n.t("csv_rails.#{f}") }.join(',')
89
- assert_match /^#{translated}/, User.where('id < 1').to_csv(:i18n_scope => 'csv_rails')
88
+ translated = [:id].map{|f| I18n.t("csv_rails.#{f}") }.join(',')
89
+ assert_match /^#{translated},#{User.human_attribute_name(:name)}/, User.where('id < 1').to_csv(:i18n_scope => 'csv_rails')
90
90
  I18n.locale = :en
91
91
  end
92
92
 
@@ -36,11 +36,17 @@ class CsvRails::ArrayTest < ActiveSupport::TestCase
36
36
 
37
37
  test ".to_csv only it includes ActiveRecord instance" do
38
38
  assert_nothing_raised do
39
- [User.create(:name => 'satomicchy')].to_csv
39
+ assert_match /^#{I18n.t("csv_rails.id")},#{User.human_attribute_name(:name)}/, [User.create(:name => 'satomicchy')].to_csv(:i18n_scope => 'csv_rails')
40
40
  end
41
41
  end
42
42
 
43
43
  test ".to_csv using empty array" do
44
- assert_equal "", [].to_csv
44
+ assert_equal "\n", [].to_csv
45
+ end
46
+
47
+ test ".to_csv only it includes Mongoid instance" do
48
+ post = Post.create(:title => 'this is csv_rails', :body => "line\nline\nline\n")
49
+
50
+ assert_equal " type,\"\",タイトル,本文\n#{post._type},#{post._id},#{post.title},\"#{post.body}\"\n", [post].to_csv
45
51
  end
46
52
  end
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ class CsvRails::MongoidTest < ActiveSupport::TestCase
5
+ setup do
6
+ Post.create(:title => 'title', :body => "foobar") if Post.where(:title => 'title').length < 1
7
+ end
8
+
9
+ teardown do
10
+ I18n.locale = :en
11
+ end
12
+
13
+ test ".to_csv" do
14
+ assert_equal "Title,Body\ntitle,foobar\n", Post.where(:title => 'title').to_csv(:fields => [:title, :body])
15
+ end
16
+
17
+ test ".to_csv with ja locale" do
18
+ I18n.locale = :ja
19
+ assert_equal "タイトル,本文\ntitle,foobar\n", Post.where(:title => 'title').to_csv(:fields => [:title, :body])
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ class Post
2
+ include Mongoid::Document
3
+ field :title, type: String
4
+ field :body, type: String
5
+ end
@@ -1,6 +1,7 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
3
  require 'rails/all'
4
+ require 'mongoid'
4
5
 
5
6
  Bundler.require
6
7
  require "csv_rails"
@@ -1,7 +1,6 @@
1
1
  ja:
2
2
  csv_rails:
3
3
  id: あいでぃー
4
- name: なまえ
5
4
  activerecord:
6
5
  attributes:
7
6
  group: &groupmodel
@@ -18,3 +17,8 @@ ja:
18
17
  user/groups:
19
18
  first:
20
19
  <<: *groupmodel
20
+ mongoid:
21
+ attributes:
22
+ post:
23
+ title: タイトル
24
+ body: 本文
@@ -0,0 +1,7 @@
1
+ development: &dev
2
+ host: localhost
3
+ database: csv_rails
4
+
5
+ test:
6
+ <<: *dev
7
+