csv_rails 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +5 -0
- data/lib/csv_rails/active_model.rb +44 -0
- data/lib/csv_rails/active_record.rb +8 -39
- data/lib/csv_rails/array.rb +33 -28
- data/lib/csv_rails/mongoid.rb +17 -0
- data/lib/csv_rails/version.rb +1 -1
- data/lib/csv_rails.rb +11 -2
- data/test/csv_rails/active_record_test.rb +2 -2
- data/test/csv_rails/array_test.rb +8 -2
- data/test/csv_rails/mongoid_test.rb +21 -0
- data/test/dummy/app/models/post.rb +5 -0
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/locales/ja.yml +5 -1
- data/test/dummy/config/mongoid.yml +7 -0
- data/test/dummy/log/test.log +36437 -0
- data/test/test_helper.rb +14 -0
- metadata +36 -6
    
        data/README.rdoc
    CHANGED
    
    
| @@ -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 | 
| 6 | 
            -
                   | 
| 7 | 
            -
                   | 
| 8 | 
            -
             | 
| 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  | 
| 36 | 
            -
                  def  | 
| 37 | 
            -
                     | 
| 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
         | 
    
        data/lib/csv_rails/array.rb
    CHANGED
    
    | @@ -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 | 
            -
                 | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
                              | 
| 21 | 
            -
             | 
| 22 | 
            -
                              | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 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
         | 
    
        data/lib/csv_rails/version.rb
    CHANGED
    
    
    
        data/lib/csv_rails.rb
    CHANGED
    
    | @@ -1,9 +1,18 @@ | |
| 1 1 | 
             
            require 'csv_rails/array'
         | 
| 2 | 
            -
            require 'csv_rails/ | 
| 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 | 
| 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 | 
            -
             | 
| 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
         |