Class: Ruport::Data::Record

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Controller::Hooks
Defined in:
lib/ruport/data/record.rb

Overview

Overview

Data::Records are the work-horse of Ruport’s data model. These can behave as Array-like, Hash-like, or Struct-like objects. They are used as the base element for Data::Table

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Controller::Hooks

#as, included, #save_as

Constructor Details

#initialize(data, options = {}) ⇒ Record

Creates a new Record object. If the :attributes keyword is specified, Hash-like and Struct-like access will be enabled. Otherwise, Record elements may be accessed ordinally, like an Array.

A Record can accept either a Hash or an Array as its data.

Examples:

a = Record.new [1,2,3]
a[1] #=> 2

b = Record.new [1,2,3], :attributes => %w[a b c]
b[1]   #=> 2  
b['a'] #=> 1
b.c    #=> 3

c = Record.new {"a" => 1, "c" => 3, "b" => 2}, :attributes => %w[a b c]
c[1]   #=> 2
c['a'] #=> 1
c.c    #=> 3

d = Record.new { "a" => 1, "c" => 3, "b" => 2 }
d[1]   #=> ? (without attributes, you cannot rely on order)
d['a'] #=> 1
d.c    #=> 3


53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ruport/data/record.rb', line 53

def initialize(data,options={})
  data = data.dup
  case(data)
  when Array
    @attributes = options[:attributes] || (0...data.length).to_a
    @data = @attributes.each_with_object({}) { |a, h| h[a.freeze] = data.shift }
  when Hash
    @data = data
    @attributes = options[:attributes] || @data.keys
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(id, *args, &block) ⇒ Object

Provides accessor style methods for attribute access.

Example:

my_record.foo = 2
my_record.foo #=> 2

Also provides a shortcut for the as() method by converting a call to to_format_name into a call to as(:format_name)



274
275
276
277
278
279
280
281
282
283
284
# File 'lib/ruport/data/record.rb', line 274

def method_missing(id,*args,&block)
  k = id.to_s.gsub(/=$/,"")
  key_index = @attributes.index(k) || @attributes.index(k.to_sym)

  if key_index
    args[0] ? self[key_index] = args[0] : self[key_index]
  else
    return as($1.to_sym,*args,&block) if id.to_s =~ /^to_(.*)/ 
    super
  end
end

Instance Attribute Details

#attributesObject

Returns a copy of the attributes from this Record.

Example:

a = Data::Record.new([1,2],:attributes => %w[a b])
a.attributes #=> ["a","b"]


76
77
78
# File 'lib/ruport/data/record.rb', line 76

def attributes
  @attributes.dup
end

#dataObject (readonly)

The data for the record



85
86
87
# File 'lib/ruport/data/record.rb', line 85

def data
  @data
end

Class Method Details

.inherited(base) ⇒ Object

:nodoc:



239
240
241
# File 'lib/ruport/data/record.rb', line 239

def self.inherited(base) #:nodoc:
  base.renders_as_row
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

If attributes and to_a are equivalent, then == evaluates to true. Otherwise, == returns false.



183
184
185
186
# File 'lib/ruport/data/record.rb', line 183

def ==(other)
   @attributes.eql?(other.attributes) &&
   to_a == other.to_a
end

#[](index) ⇒ Object

Allows either Array or Hash-like indexing.

Examples:

my_record[1] 
my_record["foo"]


102
103
104
105
106
107
108
109
# File 'lib/ruport/data/record.rb', line 102

def [](index)
  case(index)
  when Integer
    @data[@attributes[index]]
  else
    @data[index]
  end
end

#[]=(index, value) ⇒ Object

Allows setting a value at an index.

Examples:

my_record[1] = "foo" 
my_record["bar"] = "baz"


118
119
120
121
122
123
124
125
126
# File 'lib/ruport/data/record.rb', line 118

def []=(index,value)
  case(index)
  when Integer
    @data[@attributes[index]] = value
  else
    @data[index] = value
    @attributes << index unless @attributes.include? index
  end
end

#eachObject

Yields each element of the Record. Does not provide attribute names.



195
196
197
# File 'lib/ruport/data/record.rb', line 195

def each 
  to_a.each { |e| yield(e) }
end

#get(name) ⇒ Object

Indifferent access to attributes.

Examples:

record.get(:foo) # looks for an attribute "foo" or :foo,
                   or calls the method <tt>foo</tt>

record.get("foo") # looks for an attribute "foo" or :foo

record.get(0) # Gets the first element


139
140
141
142
143
144
145
146
147
148
# File 'lib/ruport/data/record.rb', line 139

def get(name)
  case name
  when String,Symbol
    self[name] || send(name)
  when Integer
    self[name]
  else
    raise ArgumentError, "Whatchu Talkin' Bout, Willis?"
  end
end

#hashObject

Provides a unique hash value. If a Record contains the same data and attributes as another Record, they will hash to the same value, even if they are not the same object. This is similar to the way Array works, but different from Hash and other objects.



248
249
250
# File 'lib/ruport/data/record.rb', line 248

def hash
  @attributes.hash + to_a.hash
end

#initialize_copy(from) ⇒ Object

Create a copy of the Record.

Example:

one = Record.new([1,2,3,4],:attributes => %w[a b c d])
two = one.dup


259
260
261
262
# File 'lib/ruport/data/record.rb', line 259

def initialize_copy(from) #:nodoc:
   @data = from.data.dup
   @attributes = from.attributes.dup
end

#rename_attribute(old_name, new_name, update_index = true) ⇒ Object

Takes an old name and a new name and renames an attribute.

The third option, update_index is for internal use.



206
207
208
209
# File 'lib/ruport/data/record.rb', line 206

def rename_attribute(old_name,new_name,update_index=true)
  @attributes[@attributes.index(old_name)] = new_name if update_index
  @data[new_name] = @data.delete(old_name)
end

#reorder(*indices) ⇒ Object

Allows you to change the order of or reduce the number of columns in a Record.

Example:

a = Data::Record.new([1,2,3,4],:attributes => %w[a b c d])
a.reorder("a","d","b")
a.attributes #=> ["a","d","b"]
a.data #=> [1,4,2]


220
221
222
223
224
225
226
227
228
229
230
# File 'lib/ruport/data/record.rb', line 220

def reorder(*indices)
  indices[0].kind_of?(Array) && indices.flatten!
  if indices.all? { |i| i.kind_of? Integer } 
    raise ArgumentError unless indices.all? { |i| @attributes[i] }
    self.attributes = indices.map { |i| @attributes[i] }
  else
    raise ArgumentError unless (indices - @attributes).empty?
    self.attributes = indices
  end
  self
end

#sizeObject Also known as: length

The size of the record (the number of items in the record’s data).



88
# File 'lib/ruport/data/record.rb', line 88

def size; @data.size; end

#to_aObject

Converts a Record into an Array.

Example:

a = Data::Record.new([1,2],:attributes => %w[a b])
a.to_a #=> [1,2]


161
162
163
# File 'lib/ruport/data/record.rb', line 161

def to_a
  @attributes.map { |a| @data[a] }
end

#to_hashObject

Converts a Record into a Hash.

Example:

a = Data::Record.new([1,2],:attributes => %w[a b])
a.to_hash #=> {"a" => 1, "b" => 2}


172
173
174
# File 'lib/ruport/data/record.rb', line 172

def to_hash
  @data.dup
end