ruport 0.4.23 → 0.4.99
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +16 -8
- data/CHANGELOG +30 -1
- data/README +144 -114
- data/Rakefile +12 -4
- data/TODO +4 -7
- data/bin/rope +21 -28
- data/examples/line_graph.rb +36 -0
- data/examples/sample_invoice_report.rb +1 -1
- data/examples/simple_graph.rb +8 -0
- data/lib/SVG/Graph/Bar.rb +137 -0
- data/lib/SVG/Graph/BarBase.rb +140 -0
- data/lib/SVG/Graph/BarHorizontal.rb +136 -0
- data/lib/SVG/Graph/Graph.rb +977 -0
- data/lib/SVG/Graph/Line.rb +444 -0
- data/lib/SVG/Graph/Pie.rb +394 -0
- data/lib/SVG/Graph/Plot.rb +494 -0
- data/lib/SVG/Graph/Schedule.rb +373 -0
- data/lib/SVG/Graph/TimeSeries.rb +241 -0
- data/lib/ruport.rb +2 -2
- data/lib/ruport/config.rb +47 -3
- data/lib/ruport/data/collection.rb +17 -1
- data/lib/ruport/data/record.rb +101 -8
- data/lib/ruport/data/set.rb +81 -2
- data/lib/ruport/data/set.rb.rej +147 -0
- data/lib/ruport/data/set.rb~ +73 -0
- data/lib/ruport/data/table.rb +127 -2
- data/lib/ruport/data/taggable.rb +21 -2
- data/lib/ruport/format.rb +36 -44
- data/lib/ruport/format/engine.rb +21 -1
- data/lib/ruport/format/plugin.rb +64 -1
- data/lib/ruport/mailer.rb +70 -36
- data/lib/ruport/meta_tools.rb +15 -6
- data/lib/ruport/query.rb +1 -1
- data/lib/ruport/rails/reportable.rb +23 -1
- data/lib/ruport/report.rb +11 -11
- data/lib/ruport/report/invoice.rb +16 -0
- data/lib/ruport/system_extensions.rb +3 -55
- data/test/{tc_database.rb → _test_database.rb} +0 -0
- data/test/{tc_config.rb → test_config.rb} +0 -0
- data/test/{tc_format.rb → test_format.rb} +1 -0
- data/test/{tc_format_engine.rb → test_format_engine.rb} +14 -2
- data/test/test_graph.rb +101 -0
- data/test/{tc_invoice.rb → test_invoice.rb} +7 -1
- data/test/test_mailer.rb +108 -0
- data/test/test_meta_tools.rb +14 -0
- data/test/{tc_plugin.rb → test_plugin.rb} +12 -1
- data/test/{tc_query.rb → test_query.rb} +0 -0
- data/test/{tc_record.rb → test_record.rb} +9 -0
- data/test/{tc_report.rb → test_report.rb} +2 -1
- data/test/{tc_ruport.rb → test_ruport.rb} +0 -0
- data/test/test_set.rb +118 -0
- data/test/test_set.rb.rej +16 -0
- data/test/{tc_set.rb → test_set.rb~} +17 -0
- data/test/{tc_sql_split.rb → test_sql_split.rb} +0 -0
- data/test/{tc_table.rb → test_table.rb} +15 -0
- data/test/{tc_taggable.rb → test_taggable.rb} +0 -0
- data/test/unit.log +361 -0
- metadata +52 -30
- data/examples/bar.pdf +0 -193
- data/examples/f.log +0 -5
- data/examples/foo.pdf +0 -193
- data/lib/ruport/format/document.rb +0 -78
- data/lib/ruport/format/open_node.rb +0 -38
- data/test/tc_data_row.rb +0 -132
- data/test/tc_data_set.rb +0 -386
- data/test/tc_document.rb +0 -42
- data/test/tc_element.rb +0 -18
- data/test/tc_page.rb +0 -42
- data/test/tc_section.rb +0 -45
- data/test/ts_all.rb +0 -12
- data/test/ts_format.rb +0 -7
@@ -0,0 +1,147 @@
|
|
1
|
+
***************
|
2
|
+
*** 8,27 ****
|
3
|
+
module Ruport::Data
|
4
|
+
class Set < Collection
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@data = ::Set.new
|
8
|
+
options[:data].each {|e| self << e} if options[:data]
|
9
|
+
end
|
10
|
+
|
11
|
+
- def <<(other)
|
12
|
+
case other
|
13
|
+
when Record
|
14
|
+
@data << other
|
15
|
+
when Array
|
16
|
+
@data << Record.new(other)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def dup
|
21
|
+
a = self.class.new(:data=>@data)
|
22
|
+
a.tags = tags.dup
|
23
|
+
--- 8,42 ----
|
24
|
+
module Ruport::Data
|
25
|
+
class Set < Collection
|
26
|
+
|
27
|
+
+ # Creates a new set containing the elements of options[:data].
|
28
|
+
+ #
|
29
|
+
+ # Set.new :data => [%w[one two three] %w[1 2 3] %w[I II III]]
|
30
|
+
def initialize(options={})
|
31
|
+
@data = ::Set.new
|
32
|
+
options[:data].each {|e| self << e} if options[:data]
|
33
|
+
end
|
34
|
+
|
35
|
+
+ # Adds the given object to the set and returns self.
|
36
|
+
+ # set = Set.new :data => [%w[one two three]]
|
37
|
+
+ # set << [5,6,7]
|
38
|
+
+ def add(other)
|
39
|
+
case other
|
40
|
+
when Record
|
41
|
+
@data << other
|
42
|
+
when Array
|
43
|
+
@data << Record.new(other)
|
44
|
+
end
|
45
|
+
+ self
|
46
|
+
end
|
47
|
+
+ alias_method :<<, :add
|
48
|
+
|
49
|
+
+ # Produces a shallow copy of the set: the same data is referenced by both
|
50
|
+
+ # the old and new sets.
|
51
|
+
+ # set = Set.new :data => [%w[one two three]]
|
52
|
+
+ # set2 = set.dup
|
53
|
+
+ # set == set2 => true
|
54
|
+
+ # set << [8,9,10]
|
55
|
+
+ # set == set2 => false
|
56
|
+
def dup
|
57
|
+
a = self.class.new(:data=>@data)
|
58
|
+
a.tags = tags.dup
|
59
|
+
***************
|
60
|
+
*** 29,53 ****
|
61
|
+
end
|
62
|
+
alias_method :clone, :dup
|
63
|
+
|
64
|
+
def ==(other)
|
65
|
+
@data == other.data
|
66
|
+
end
|
67
|
+
|
68
|
+
def |(other)
|
69
|
+
Set.new :data => (@data | other.data)
|
70
|
+
end
|
71
|
+
alias_method :union, :|
|
72
|
+
|
73
|
+
def &(other)
|
74
|
+
Set.new :data => (@data & other.data)
|
75
|
+
end
|
76
|
+
alias_method :intersection, :&
|
77
|
+
|
78
|
+
- # Set difference
|
79
|
+
def -(other)
|
80
|
+
Set.new :data => (@data - other.data)
|
81
|
+
end
|
82
|
+
alias_method :difference, :-
|
83
|
+
|
84
|
+
def_delegators :@data, :each
|
85
|
+
end
|
86
|
+
--- 44,104 ----
|
87
|
+
end
|
88
|
+
alias_method :clone, :dup
|
89
|
+
|
90
|
+
+ # Equality. Two sets are equal if they contain the same set of objects.
|
91
|
+
+ # s1 = Set.new :data => [[1,2,3]]
|
92
|
+
+ # s2 = Set.new :data => [[1,2,3]]
|
93
|
+
+ # s1 == s2 => true
|
94
|
+
def ==(other)
|
95
|
+
@data == other.data
|
96
|
+
end
|
97
|
+
|
98
|
+
+ # Union. Returns a new set containing the union of the objects contained in
|
99
|
+
+ # the two sets.
|
100
|
+
+ # s1 = Set.new :data => [[1,2,3]]
|
101
|
+
+ # s2 = Set.new :data => [[4,5,6]]
|
102
|
+
+ # s3 = s1 | s2
|
103
|
+
+ # s4 = Set.new :data => [[1,2,3], [4,5,6]]
|
104
|
+
+ # s3 == s4 => true
|
105
|
+
def |(other)
|
106
|
+
Set.new :data => (@data | other.data)
|
107
|
+
end
|
108
|
+
alias_method :union, :|
|
109
|
+
+ alias_method :+, :|
|
110
|
+
|
111
|
+
+ # Intersection. Returns a new set containing the objects common to the two
|
112
|
+
+ # sets.
|
113
|
+
+ # s1 = Set.new :data => [%w[a b c],[1,2,3]]
|
114
|
+
+ # s2 = Set.new :data => [%w[a b c],[4,5,6]]
|
115
|
+
+ # s3 = s1 | s2
|
116
|
+
+ # s4 = Set.new :data => [%w[a b c]]
|
117
|
+
+ # s3 == s4 => true
|
118
|
+
def &(other)
|
119
|
+
Set.new :data => (@data & other.data)
|
120
|
+
end
|
121
|
+
alias_method :intersection, :&
|
122
|
+
|
123
|
+
+ # Difference. Returns a new set containing those objects present in this
|
124
|
+
+ # set but not the other.
|
125
|
+
+ # s1 = Set.new :data => [%w[a b c],[1,2,3]]
|
126
|
+
+ # s2 = Set.new :data => [%w[a b c],[4,5,6]]
|
127
|
+
+ # s3 = s1 | s2
|
128
|
+
+ # s4 = Set.new :data => [[1, 2, 3]]
|
129
|
+
+ # s3 == s4 => true
|
130
|
+
def -(other)
|
131
|
+
Set.new :data => (@data - other.data)
|
132
|
+
end
|
133
|
+
alias_method :difference, :-
|
134
|
+
+
|
135
|
+
+ # Exclusion. Returns a new set containing those objects in this set or the
|
136
|
+
+ # other set but not in both.
|
137
|
+
+ # s1 = Set.new :data => [%w[a b c],[1,2,3]]
|
138
|
+
+ # s2 = Set.new :data => [%w[a b c],[4,5,6]]
|
139
|
+
+ # s3 = s1 | s2
|
140
|
+
+ # s4 = Set.new :data => [[1, 2, 3],[4,5,6]]
|
141
|
+
+ # s3 == s4 => true
|
142
|
+
+ def ^(other)
|
143
|
+
+ Set.new :data => (@data ^ other.data)
|
144
|
+
+ end
|
145
|
+
|
146
|
+
def_delegators :@data, :each
|
147
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# The Ruport Data Collections.
|
2
|
+
# Authors: Gregory Brown / Dudley Flanders
|
3
|
+
#
|
4
|
+
# This is Free Software. For details, see LICENSE and COPYING
|
5
|
+
# Copyright 2006 by respective content owners, all rights reserved.
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
module Ruport::Data
|
9
|
+
class Set < Collection
|
10
|
+
|
11
|
+
# Creates a new set containing the elements of options[:data].
|
12
|
+
def initialize(options={})
|
13
|
+
@data = ::Set.new
|
14
|
+
options[:data].each {|e| self << e} if options[:data]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Adds the given object to the set and returns self.
|
18
|
+
def add(other)
|
19
|
+
case other
|
20
|
+
when Record
|
21
|
+
@data << other
|
22
|
+
when Array
|
23
|
+
@data << Record.new(other)
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
alias_method :<<, :add
|
28
|
+
|
29
|
+
# Produces a shallow copy of the set: the same data is referenced by both
|
30
|
+
# the old and new sets.
|
31
|
+
def dup
|
32
|
+
a = self.class.new(:data=>@data)
|
33
|
+
a.tags = tags.dup
|
34
|
+
return a
|
35
|
+
end
|
36
|
+
alias_method :clone, :dup
|
37
|
+
|
38
|
+
# Equality. Two sets are equal if they contain the same set of objects.
|
39
|
+
def ==(other)
|
40
|
+
@data == other.data
|
41
|
+
end
|
42
|
+
|
43
|
+
# Union. Returns a new set containing the union of the objects contained in
|
44
|
+
# the two sets.
|
45
|
+
def |(other)
|
46
|
+
Set.new :data => (@data | other.data)
|
47
|
+
end
|
48
|
+
alias_method :union, :|
|
49
|
+
alias_method :+, :|
|
50
|
+
|
51
|
+
# Intersection. Returns a new set containing the objects common to the two
|
52
|
+
# sets.
|
53
|
+
def &(other)
|
54
|
+
Set.new :data => (@data & other.data)
|
55
|
+
end
|
56
|
+
alias_method :intersection, :&
|
57
|
+
|
58
|
+
# Difference. Returns a new set containing those objects present in this
|
59
|
+
# set but not the other.
|
60
|
+
def -(other)
|
61
|
+
Set.new :data => (@data - other.data)
|
62
|
+
end
|
63
|
+
alias_method :difference, :-
|
64
|
+
|
65
|
+
# Exclusion. Returns a new set containing those objects in this set or the
|
66
|
+
# other set but not in both.
|
67
|
+
def ^(other)
|
68
|
+
Set.new :data => (@data ^ other.data)
|
69
|
+
end
|
70
|
+
|
71
|
+
def_delegators :@data, :each
|
72
|
+
end
|
73
|
+
end
|
data/lib/ruport/data/table.rb
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
+
# The Ruport Data Collections.
|
2
|
+
# Authors: Gregory Brown / Dudley Flanders
|
3
|
+
#
|
4
|
+
# This is Free Software. For details, see LICENSE and COPYING
|
5
|
+
# Copyright 2006 by respective content owners, all rights reserved.
|
6
|
+
|
1
7
|
class Array
|
8
|
+
# Converts an array to a Ruport::Data::Table object, ready to
|
9
|
+
# use in your reports.
|
10
|
+
#
|
11
|
+
# [[1,2],[3,4]].to_table(%w[a b])
|
2
12
|
def to_table(options={})
|
3
13
|
options = { :column_names => options } if options.kind_of? Array
|
4
14
|
Ruport::Data::Table.new({:data => self}.merge(options))
|
@@ -6,7 +16,29 @@ class Array
|
|
6
16
|
end
|
7
17
|
|
8
18
|
module Ruport::Data
|
19
|
+
|
20
|
+
# This class is one of the core classes for building and working with data
|
21
|
+
# in Ruport. The idea is to get your data into a standard form, regardless
|
22
|
+
# of its source (a database, manual arrays, ActiveRecord, CSVs, etc.).
|
23
|
+
#
|
24
|
+
# Table is intended to be used as the data store for structured, tabular
|
25
|
+
# data - Ruport::Data::Set is an alternate intermediary data store intended
|
26
|
+
# for less structured data.
|
27
|
+
#
|
28
|
+
# Once your data is in a Ruport::Data::Table object, it can be manipulated
|
29
|
+
# to suit your needs, then used to build a report.
|
30
|
+
#
|
31
|
+
# Included in this class are methods to create Tables manually and from CSV
|
32
|
+
# files.
|
33
|
+
#
|
34
|
+
# For building a table using ActiveRecord, have a look at Ruport::Reportable.
|
9
35
|
class Table < Collection
|
36
|
+
|
37
|
+
# Creates a new table based on the supplied options.
|
38
|
+
# Valid options are :data and :column_names.
|
39
|
+
#
|
40
|
+
# table = Table.new({:data => [1,2,3], [3,4,5],
|
41
|
+
# :column_names => %w[a b c]})
|
10
42
|
def initialize(options={})
|
11
43
|
@column_names = options[:column_names].dup if options[:column_names]
|
12
44
|
@data = []
|
@@ -15,20 +47,42 @@ module Ruport::Data
|
|
15
47
|
|
16
48
|
attr_reader :column_names
|
17
49
|
|
50
|
+
# Sets the column names for this table. The single parameter should be
|
51
|
+
# an array listing the names of the columns.
|
52
|
+
#
|
53
|
+
# tbl = Table.new({:data => [1,2,3], [3,4,5], :column_names => %w[a b c]})
|
54
|
+
# tbl.column_names = %w[e f g]
|
18
55
|
def column_names=(other)
|
19
56
|
@column_names = other.dup
|
20
57
|
map { |r| r.attributes = @column_names }
|
21
58
|
end
|
22
59
|
|
60
|
+
# Compares this table to another table and returns true if
|
61
|
+
# both the data and column names are equal
|
62
|
+
#
|
63
|
+
# one = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
64
|
+
# two = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
65
|
+
# one.eql?(two) #=> true
|
23
66
|
def eql?(other)
|
24
67
|
data.eql?(other.data) && column_names.eql?(other.column_names)
|
25
68
|
end
|
26
69
|
alias_method :==, :eql?
|
27
70
|
|
71
|
+
# Uses Ruport's built-in text plugin to render this table into a string
|
72
|
+
#
|
73
|
+
# data = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
74
|
+
# puts data.to_s
|
28
75
|
def to_s
|
29
76
|
as(:text)
|
30
77
|
end
|
31
78
|
|
79
|
+
# Used to add extra data to the table. The single parameter can be an
|
80
|
+
# Array, Hash or Ruport::Data::Record.
|
81
|
+
#
|
82
|
+
# data = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
83
|
+
# data << [8,9]
|
84
|
+
# data << { :a => 4, :b => 5}
|
85
|
+
# data << Ruport::Data::Record.new [5,6], :attributes => %w[a b]
|
32
86
|
def <<(other)
|
33
87
|
case other
|
34
88
|
when Array
|
@@ -39,12 +93,19 @@ module Ruport::Data
|
|
39
93
|
@data << Record.new(arr, :attributes => @column_names)
|
40
94
|
when Record
|
41
95
|
raise ArgumentError unless column_names.eql? other.attributes
|
42
|
-
@data << Record.new(other.
|
96
|
+
@data << Record.new(other.data, :attributes => @column_names)
|
97
|
+
@data.last.tags = other.tags.dup
|
43
98
|
end
|
44
99
|
self
|
45
100
|
end
|
46
|
-
|
101
|
+
|
102
|
+
# Reorders the columns that exist in the table. Operates directly
|
103
|
+
# on this table.
|
104
|
+
#
|
105
|
+
# data = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
106
|
+
# data.reorder!([1,0])
|
47
107
|
def reorder!(*indices)
|
108
|
+
indices = indices[0] if indices[0].kind_of? Array
|
48
109
|
@column_names = if indices.all? { |i| i.kind_of? Integer }
|
49
110
|
indices.map { |i| @column_names[i] }
|
50
111
|
else
|
@@ -53,10 +114,21 @@ module Ruport::Data
|
|
53
114
|
@data.each { |r| r.reorder! *indices }; self
|
54
115
|
end
|
55
116
|
|
117
|
+
# Returns a copy of the table with its columns in the requested order.
|
118
|
+
#
|
119
|
+
# one = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
120
|
+
# two = one.reorder!([1,0])
|
56
121
|
def reorder(*indices)
|
57
122
|
dup.reorder! *indices
|
58
123
|
end
|
59
124
|
|
125
|
+
# Adds an extra column to the table. Accepts an options Hash as its
|
126
|
+
# only parameter which should contain 2 keys - :name and :fill.
|
127
|
+
# :name specifies the new columns name, and :fill the default value to
|
128
|
+
# use for the column in existing rows.
|
129
|
+
#
|
130
|
+
# data = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
131
|
+
# data.append_coulmn({:name => 'new_column', :fill => 1)
|
60
132
|
def append_column(options={})
|
61
133
|
self.column_names += [options[:name]] if options[:name]
|
62
134
|
if block_given?
|
@@ -66,10 +138,32 @@ module Ruport::Data
|
|
66
138
|
end
|
67
139
|
end
|
68
140
|
|
141
|
+
# Removes a column from the table. Any values in the specified column are
|
142
|
+
# lost.
|
143
|
+
# data = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
144
|
+
# data.append_column({:name => 'new_column', :fill => 1)
|
145
|
+
# data.remove_column({:name => 'new_column')
|
146
|
+
# data == Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
147
|
+
# => true
|
148
|
+
def remove_column(options={})
|
149
|
+
raise ArgumentError unless column_names.include? options[:name]
|
150
|
+
reorder! column_names - [options[:name]]
|
151
|
+
end
|
152
|
+
|
153
|
+
# Create a shallow copy of the table: the same data elements are referenced
|
154
|
+
# by both the old and new table.
|
155
|
+
#
|
156
|
+
# one = Table.new({:data => [1,2], [3,4], :column_names => %w[a b]})
|
157
|
+
# two = one.dup
|
69
158
|
def dup
|
70
159
|
a = self.class.new(:data => @data, :column_names => @column_names)
|
160
|
+
a.tags = tags.dup
|
161
|
+
return a
|
71
162
|
end
|
72
163
|
|
164
|
+
# Loads a CSV file directly into a table using the fasterCSV library.
|
165
|
+
#
|
166
|
+
# data = Table.load('mydata.csv')
|
73
167
|
def self.load(csv_file, options = {})
|
74
168
|
options = {:has_names => true}.merge(options)
|
75
169
|
require "fastercsv"
|
@@ -88,6 +182,37 @@ module Ruport::Data
|
|
88
182
|
end ; loaded_data
|
89
183
|
end
|
90
184
|
|
185
|
+
|
186
|
+
|
187
|
+
# Allows you to split tables into multiple tables for grouping.
|
188
|
+
#
|
189
|
+
# Example:
|
190
|
+
#
|
191
|
+
# a = Table.new(:column_name => %w[name a b c])
|
192
|
+
# a << ["greg",1,2,3]
|
193
|
+
# a << ["joe", 2,3,4]
|
194
|
+
# a << ["greg",7,8,9]
|
195
|
+
# a << ["joe", 1,2,3]
|
196
|
+
#
|
197
|
+
# b = a.split :group => "name"
|
198
|
+
#
|
199
|
+
# b.greg.eql? [[1,2,3],[7,8,9]].to_table(%w[a b c]) #=> true
|
200
|
+
# b["joe"].eql? [[2,3,4],[1,2,3]].to_table(%w[a b c]) #=> true
|
201
|
+
#
|
202
|
+
# You can also pass an array to :group, and the resulting attributes in
|
203
|
+
# the group will be joined by an underscore.
|
204
|
+
#
|
205
|
+
# Example:
|
206
|
+
#
|
207
|
+
# a = Table.new(:column_names => %w[first_name last_name x]
|
208
|
+
# a << %w[greg brown foo]
|
209
|
+
# a << %w[greg gibson bar]
|
210
|
+
# a << %w[greg brown baz]
|
211
|
+
#
|
212
|
+
# b = a.split :group => %w[first_name last_name]
|
213
|
+
# a.greg_brown.length #=> 2
|
214
|
+
# a["greg_gibson"].length #=> 1
|
215
|
+
# a.greg_brown[0].x #=> "foo"
|
91
216
|
def split(options={})
|
92
217
|
if options[:group].kind_of? Array
|
93
218
|
group = map { |r| options[:group].map { |e| r[e] } }.uniq
|
data/lib/ruport/data/taggable.rb
CHANGED
@@ -1,23 +1,42 @@
|
|
1
|
+
# The Ruport Data Collections.
|
2
|
+
# Authors: Gregory Brown / Dudley Flanders
|
3
|
+
#
|
4
|
+
# This is Free Software. For details, see LICENSE and COPYING
|
5
|
+
# Copyright 2006 by respective content owners, all rights reserved.
|
1
6
|
module Ruport::Data
|
2
7
|
|
8
|
+
# This module provides a simple mechanism for tagging arbitrary objects. This
|
9
|
+
# provides the necessary methods to set and retrieve tags which can consist of
|
10
|
+
# any Ruby object. This is used by Data::Record and the Ruport Data
|
11
|
+
# Collections.
|
3
12
|
module Taggable
|
4
13
|
|
14
|
+
# Adds a tag to the object
|
15
|
+
# taggable_obj.tag :spiffy
|
5
16
|
def tag(tag_name)
|
6
17
|
tags << tag_name unless has_tag? tag_name
|
7
18
|
end
|
8
|
-
|
19
|
+
|
20
|
+
# Removes a tag
|
21
|
+
# taggable_obj.delete_tag :not_so_spiffy
|
9
22
|
def delete_tag(tag_name)
|
10
23
|
tags.delete tag_name
|
11
24
|
end
|
12
25
|
|
26
|
+
# Checks to see if a tag is present
|
27
|
+
# taggable_obj.has_tag? :spiffy #=> true
|
13
28
|
def has_tag?(tag_name)
|
14
29
|
tags.include? tag_name
|
15
30
|
end
|
16
31
|
|
32
|
+
# Returns an array of tags.
|
33
|
+
# taggable_obj.tags #=> [:spiffy, :kind_of_spiffy]
|
17
34
|
def tags
|
18
35
|
@ruport_tags ||= []
|
19
36
|
end
|
20
|
-
|
37
|
+
|
38
|
+
# Sets the tags to some array
|
39
|
+
# taggable_obj.tags = [:really_dang_spiffy, :the_most_spiffy]
|
21
40
|
def tags=(tags_list)
|
22
41
|
@ruport_tags = tags_list
|
23
42
|
end
|