make_exportable 1.0.1 → 1.0.2

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.
Files changed (4) hide show
  1. data/Gemfile.lock +43 -0
  2. data/VERSION +1 -1
  3. data/lib/make_exportable/core.rb +108 -107
  4. metadata +5 -4
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (2.3.6)
5
+ actionpack (= 2.3.6)
6
+ actionpack (2.3.6)
7
+ activesupport (= 2.3.6)
8
+ rack (~> 1.1.0)
9
+ activerecord (2.3.6)
10
+ activesupport (= 2.3.6)
11
+ activeresource (2.3.6)
12
+ activesupport (= 2.3.6)
13
+ activesupport (2.3.6)
14
+ gemcutter (0.5.0)
15
+ json_pure
16
+ git (1.2.5)
17
+ jeweler (1.4.0)
18
+ gemcutter (>= 0.1.0)
19
+ git (>= 1.2.5)
20
+ rubyforge (>= 2.0.0)
21
+ json_pure (1.4.3)
22
+ rack (1.1.0)
23
+ rails (2.3.6)
24
+ actionmailer (= 2.3.6)
25
+ actionpack (= 2.3.6)
26
+ activerecord (= 2.3.6)
27
+ activeresource (= 2.3.6)
28
+ activesupport (= 2.3.6)
29
+ rake (>= 0.8.3)
30
+ rake (0.8.7)
31
+ rspec (1.3.0)
32
+ rubyforge (2.0.4)
33
+ json_pure (>= 1.1.7)
34
+ sqlite3-ruby (1.3.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ jeweler
41
+ rails
42
+ rspec
43
+ sqlite3-ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
@@ -22,117 +22,118 @@ module MakeExportable #:nodoc:
22
22
 
23
23
  protected
24
24
 
25
- # <tt>make_exportable</tt> is an ActiveRecord method that, when called, add
26
- # methods to a particular class to make exporting data from that class easier.
27
- #
28
- # Example:
29
- #
30
- # class Customer < ActiveRecord::Base
31
- # make_exportable
32
- # end
33
- # Customer.to_export(:csv)
34
- #
35
- # An optional hash of options can be passed as an argument to establish the default
36
- # export parameters.
37
- #
38
- # These options include:
39
- # * :only and :except - specify columns or methods to export (defaults to all columns)
40
- # * :as - specify formats to allow for exporting (defaults to all formats)
41
- # * :scopes - specify scopes to be called on the class before exporting
42
- # * find options - for Rails 2.3 and earlier compatibility, standard find options
43
- # are supported (:conditions, :order, :limit, :offset, etc.). These will be deprecated
44
- # and removed in future versions.
45
- #
46
- # Examples:
47
- #
48
- # class Customer < ActiveRecord::Base
49
- # make_exportable :only => [:id, :username, :full_name]
50
- # end
51
- #
52
- # class Customer < ActiveRecord::Base
53
- # make_exportable :except => [:id, :password], :scopes => [:new_signups, :with_referals],
54
- # :as => [:csv, :tsv, :xls]
55
- # end
56
- #
57
- # class Customer < ActiveRecord::Base
58
- # make_exportable :conditions => {:active => true}, :order => 'last_name ASC, first_name ASC',
59
- # :as => [:json, :html, :xml]
60
- # end
61
- #
62
- def make_exportable(options={})
63
- # register the class as exportable
64
- MakeExportable.exportable_classes[self.class_name] = self
65
-
66
- # remove any invalid options
67
- valid_options = [:as, :only, :except, :scopes, :conditions, :order, :include,
68
- :group, :having, :limit, :offset, :joins]
69
- options.slice!(*valid_options)
70
-
71
- # Determine the exportable formats, default to all registered formats
72
- options[:formats] = MakeExportable.exportable_formats.keys
73
- if format_options = options.delete(:as)
74
- options[:formats] = options[:formats] & Array.wrap(format_options).map(&:to_sym)
75
- end
76
- # Handle case when :as option was sent, but with no valid formats
77
- if options[:formats].blank?
78
- valid_formats = MakeExportable.exportable_formats.keys.map {|f| ":#{f}"}
79
- raise MakeExportable::FormatNotFound.new("No valid export formats. Use: #{valid_formats.join(', ')}")
80
- end
25
+ # <tt>make_exportable</tt> is an ActiveRecord method that, when called, add
26
+ # methods to a particular class to make exporting data from that class easier.
27
+ #
28
+ # Example:
29
+ #
30
+ # class Customer < ActiveRecord::Base
31
+ # make_exportable
32
+ # end
33
+ # Customer.to_export(:csv)
34
+ #
35
+ # An optional hash of options can be passed as an argument to establish the default
36
+ # export parameters.
37
+ #
38
+ # These options include:
39
+ # * :only and :except - specify columns or methods to export (defaults to all columns)
40
+ # * :as - specify formats to allow for exporting (defaults to all formats)
41
+ # * :scopes - specify scopes to be called on the class before exporting
42
+ # * find options - for Rails 2.3 and earlier compatibility, standard find options
43
+ # are supported (:conditions, :order, :limit, :offset, etc.). These will be deprecated
44
+ # and removed in future versions.
45
+ #
46
+ # Examples:
47
+ #
48
+ # class Customer < ActiveRecord::Base
49
+ # make_exportable :only => [:id, :username, :full_name]
50
+ # end
51
+ #
52
+ # class Customer < ActiveRecord::Base
53
+ # make_exportable :except => [:id, :password], :scopes => [:new_signups, :with_referals],
54
+ # :as => [:csv, :tsv, :xls]
55
+ # end
56
+ #
57
+ # class Customer < ActiveRecord::Base
58
+ # make_exportable :conditions => {:active => true}, :order => 'last_name ASC, first_name ASC',
59
+ # :as => [:json, :html, :xml]
60
+ # end
61
+ #
62
+ def make_exportable(options={})
63
+ return unless self.table_exists?
64
+ # register the class as exportable
65
+ MakeExportable.exportable_classes[self.class_name] = self
81
66
 
82
- # Determine the exportable columns, default to all columns and then
83
- # remove columns using the :only and :except options
84
- options[:columns] = column_names.map(&:to_sym)
85
- if only_options = options.delete(:only)
86
- options[:columns] = Array.wrap(only_options).map(&:to_sym)
87
- end
88
- if except_options = options.delete(:except)
89
- options[:columns] = options[:columns] - Array.wrap(except_options).map(&:to_sym)
90
- end
67
+ # remove any invalid options
68
+ valid_options = [:as, :only, :except, :scopes, :conditions, :order, :include,
69
+ :group, :having, :limit, :offset, :joins]
70
+ options.slice!(*valid_options)
91
71
 
92
- options[:scopes] ||= []
72
+ # Determine the exportable formats, default to all registered formats
73
+ options[:formats] = MakeExportable.exportable_formats.keys
74
+ if format_options = options.delete(:as)
75
+ options[:formats] = options[:formats] & Array.wrap(format_options).map(&:to_sym)
76
+ end
77
+ # Handle case when :as option was sent, but with no valid formats
78
+ if options[:formats].blank?
79
+ valid_formats = MakeExportable.exportable_formats.keys.map {|f| ":#{f}"}
80
+ raise MakeExportable::FormatNotFound.new("No valid export formats. Use: #{valid_formats.join(', ')}")
81
+ end
93
82
 
94
- # exportable options will be :formats, :columns, :scopes & find options
95
- write_inheritable_attribute :exportable_options, options
96
- class_inheritable_reader :exportable_options
83
+ # Determine the exportable columns, default to all columns and then
84
+ # remove columns using the :only and :except options
85
+ options[:columns] = column_names.map(&:to_sym)
86
+ if only_options = options.delete(:only)
87
+ options[:columns] = Array.wrap(only_options).map(&:to_sym)
88
+ end
89
+ if except_options = options.delete(:except)
90
+ options[:columns] = options[:columns] - Array.wrap(except_options).map(&:to_sym)
91
+ end
97
92
 
98
- extend MakeExportable::ClassMethods
99
- include MakeExportable::InstanceMethods
93
+ options[:scopes] ||= []
100
94
 
101
- end
95
+ # exportable options will be :formats, :columns, :scopes & find options
96
+ write_inheritable_attribute :exportable_options, options
97
+ class_inheritable_reader :exportable_options
98
+
99
+ extend MakeExportable::ClassMethods
100
+ include MakeExportable::InstanceMethods
101
+
102
+ end
102
103
 
103
104
  end
104
105
 
105
106
  module ClassMethods
106
107
 
107
108
  # <tt>exportable?<?tt> returns true if the class has called "make_exportable".
108
- # This is overriding the default :exportable? in ActiveRecord::Base which
109
+ # This is overriding the default :exportable? in ActiveRecord::Base which
109
110
  # always returns false.
110
- # If a format is passed as an argument, returns true only if the format is
111
+ # If a format is passed as an argument, returns true only if the format is
111
112
  # allowed for this class.
112
113
  def exportable?(format=nil)
113
114
  return exportable_options[:formats].include?(format.to_sym) if format
114
115
  return true
115
116
  end
116
117
 
117
- # <tt>to_export</tt> exports records from a class. It can be called
118
+ # <tt>to_export</tt> exports records from a class. It can be called
118
119
  # directly on an ActiveRecord class, but it can also be called on an ActiveRelation scope.
119
120
  # It takes two arguments: a format (required) and a hash of options (optional).
120
121
  #
121
122
  # The options include:
122
123
  # * :only and :except - specify columns or methods to export
123
124
  # * :scopes - specify scopes to be called on the class before exporting
124
- # * find options - for Rails 2.3 and earlier compatibility, standard find options
125
- # are supported (:conditions, :order, :limit, :offset, etc.). These will be deprecated
125
+ # * find options - for Rails 2.3 and earlier compatibility, standard find options
126
+ # are supported (:conditions, :order, :limit, :offset, etc.). These will be deprecated
126
127
  # and removed in future versions.
127
- # * :headers - supply an array of custom headers for the columns of exported attributes,
128
+ # * :headers - supply an array of custom headers for the columns of exported attributes,
128
129
  # the sizes of the header array and the exported columns must be equal.
129
- #
130
+ #
130
131
  # Examples:
131
132
  #
132
- # User.to_export(:xml, :only => [:first_name, :last_name, :username],
133
+ # User.to_export(:xml, :only => [:first_name, :last_name, :username],
133
134
  # :order => 'users.last_name ASC')
134
135
  #
135
- # User.visible.sorted_by_username.to_export('csv',
136
+ # User.visible.sorted_by_username.to_export('csv',
136
137
  # :only => [:first_name, :last_name, :username])
137
138
  #
138
139
  def to_export(format, options={})
@@ -144,16 +145,16 @@ module MakeExportable #:nodoc:
144
145
  export_string = create_report(format, export_data, :headers => options[:headers])
145
146
  return export_string
146
147
  end
147
-
148
- # <tt>get_export_data</tt> finds records for export using a combination of the default
149
- # export options and the argument options, and returns an array of arrays representing
150
- # the rows and columns of the export data. The first item ("row") in the array will be
148
+
149
+ # <tt>get_export_data</tt> finds records for export using a combination of the default
150
+ # export options and the argument options, and returns an array of arrays representing
151
+ # the rows and columns of the export data. The first item ("row") in the array will be
151
152
  # an array of strings to be used as column headers.
152
- # Valid options include :only, :except, :scopes and the standard find options.
153
+ # Valid options include :only, :except, :scopes and the standard find options.
153
154
  # See <tt>to_export</tt> for more details on the options.
154
155
  #
155
156
  # Example:
156
- #
157
+ #
157
158
  # User.get_export_data(:only => [:first_name, :last_name, :username])
158
159
  # # => [['first_name', 'last_name', 'username'], ['John', 'Doe', 'johndoe'], ['Joe', 'Smith', 'jsmith']] }
159
160
  #
@@ -164,23 +165,23 @@ module MakeExportable #:nodoc:
164
165
  return export_data
165
166
  end
166
167
 
167
- # <tt>create_report</tt> creates a report from a set of data. It takes three arguments:
168
- # a format, the data set to use for the report, and an optional hash of options.
169
- # The only meaningful option is :headers which sets the strings to be used as column
168
+ # <tt>create_report</tt> creates a report from a set of data. It takes three arguments:
169
+ # a format, the data set to use for the report, and an optional hash of options.
170
+ # The only meaningful option is :headers which sets the strings to be used as column
170
171
  # headers for the data set. The value of :headers can be:
171
172
  # * true - headers are the first row in the data set
172
173
  # * false - headers are not in the data set and should not be added
173
174
  # * array of strings to use for the column headers
174
- #
175
+ #
175
176
  # The length of the headers must match the length of each row in the data set.
176
177
  def create_report(format, data_set, options={})
177
178
  if options[:headers] === true
178
179
  options[:headers] = data_set.shift
179
180
  end
180
-
181
+
181
182
  validate_export_format(format)
182
183
  validate_export_data_lengths(data_set, options[:headers])
183
-
184
+
184
185
  format_class = MakeExportable.exportable_formats[format.to_sym]
185
186
  formater = format_class.new(data_set, options[:headers])
186
187
  return formater.generate, formater.mime_type
@@ -188,7 +189,7 @@ module MakeExportable #:nodoc:
188
189
 
189
190
  private
190
191
 
191
- # <tt>method_missing</tt> allows the class to accept dynamically named methods
192
+ # <tt>method_missing</tt> allows the class to accept dynamically named methods
192
193
  # such as: SomeClass.to_xls_export(), SomeClass.create_csv_report()
193
194
  def method_missing(method_id, *arguments)
194
195
  possible_formats = MakeExportable.exportable_formats.keys.map(&:to_s).join('|')
@@ -205,11 +206,11 @@ module MakeExportable #:nodoc:
205
206
 
206
207
  # <tt>find_export_data</tt> finds all objects of a given
207
208
  # class using a combination of the default export options and the options passed in.
208
- # Valid options include :scopes and the standard find options. It returns a collection of
209
+ # Valid options include :scopes and the standard find options. It returns a collection of
209
210
  # objects matching the find criteria.
210
211
  # See <tt>to_export</tt> for more details on the options.
211
212
  def find_export_data(options={})
212
-
213
+
213
214
  # merge with defaults then pull out the supported find and scope options
214
215
  merged_options = options.reverse_merge(exportable_options)
215
216
  find_options = merged_options.slice(:conditions, :order, :include, :group, :having, :limit, :offset, :joins)
@@ -230,12 +231,12 @@ module MakeExportable #:nodoc:
230
231
  return collection
231
232
  end
232
233
 
233
- # <tt>map_export_data</tt> takes a collection and outputs an array of arrays representing
234
- # the rows and columns of the export data. The first item ("row") in the array will be
234
+ # <tt>map_export_data</tt> takes a collection and outputs an array of arrays representing
235
+ # the rows and columns of the export data. The first item ("row") in the array will be
235
236
  # an array of strings to be used as column headers.
236
237
  # Valid options include :only and :except.
237
238
  # See <tt>to_export</tt> for more details on the options.
238
- #
239
+ #
239
240
  # User.map_export_data(User.visible, :only => [:first_name, :last_name, :username])
240
241
  # # => [['first_name', 'last_name', 'username'], ['John', 'Doe', 'johndoe'], ...]
241
242
  #
@@ -269,7 +270,7 @@ module MakeExportable #:nodoc:
269
270
  end
270
271
  end
271
272
 
272
- # <tt>validate_export_data_lengths</tt> ensures that the headers and all data rows are of the
273
+ # <tt>validate_export_data_lengths</tt> ensures that the headers and all data rows are of the
273
274
  # same size. (This is an important data integrity check if you are using NoSQL.)
274
275
  def validate_export_data_lengths(data_set, data_headers=nil)
275
276
  row_length = !data_headers.blank? ? data_headers.size : data_set[0].size
@@ -283,13 +284,13 @@ module MakeExportable #:nodoc:
283
284
  module InstanceMethods
284
285
 
285
286
  # <tt>export_attribute</tt> returns the export value of an attribute or method.
286
- # By default, this is simply the value of the attribute or method itself,
287
- # but the value can be permanently overridden with another value by defining
288
- # a method called "#{attribute}_export". The alternate method will *always*
289
- # be called in place of the original one. At a minimum, this is useful
290
- # when a date should be formatted when exporting or when booleans should
291
- # always export as "Yes"/"No". But it can do more, performing any amount of
292
- # processing or additional queries, as long as in the end it returns a value
287
+ # By default, this is simply the value of the attribute or method itself,
288
+ # but the value can be permanently overridden with another value by defining
289
+ # a method called "#{attribute}_export". The alternate method will *always*
290
+ # be called in place of the original one. At a minimum, this is useful
291
+ # when a date should be formatted when exporting or when booleans should
292
+ # always export as "Yes"/"No". But it can do more, performing any amount of
293
+ # processing or additional queries, as long as in the end it returns a value
293
294
  # for the export to use.
294
295
  # Sending an attribute name that does not exist will return an empty string.
295
296
  def export_attribute(attribute)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: make_exportable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 2
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kevin Skoglund
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-06-27 00:00:00 -04:00
19
+ date: 2010-08-06 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies: []
22
22
 
@@ -30,6 +30,7 @@ extra_rdoc_files:
30
30
  - README.rdoc
31
31
  files:
32
32
  - Gemfile
33
+ - Gemfile.lock
33
34
  - MIT-LICENSE
34
35
  - README.rdoc
35
36
  - Rakefile