constantrecord 0.0.1 → 0.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.
- data/README.rdoc +6 -5
- data/Rakefile +1 -1
- data/constantrecord.gemspec +2 -2
- data/lib/constantrecord.rb +251 -251
- data/test/constantrecord_test.rb +8 -0
- metadata +2 -2
data/README.rdoc
CHANGED
|
@@ -11,9 +11,9 @@ or
|
|
|
11
11
|
class MoreDetailedCurrency < ConstantRecord::Base
|
|
12
12
|
columns :short, :description
|
|
13
13
|
data ['EUR', 'Euro'],
|
|
14
|
-
['USD', '
|
|
15
|
-
['CAD', 'Canadian
|
|
16
|
-
['GBP', 'British
|
|
14
|
+
['USD', 'United States dollar'],
|
|
15
|
+
['CAD', 'Canadian dollar'],
|
|
16
|
+
['GBP', 'British pound sterling'],
|
|
17
17
|
['CHF', 'Swiss franc']
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -76,8 +76,9 @@ When +data+ is a simple Array, #name is the default attribute.
|
|
|
76
76
|
Currency.count :all >> 5
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
As a matter of fact, a ConstantRecord will often be used as a select field in a
|
|
80
|
+
HTML form. Therefore it comes with a special feature, that is not ActiveRecord
|
|
81
|
+
compatible. In a Form you can use:
|
|
81
82
|
|
|
82
83
|
<%= f.select :currency_id, Currency.options_for_select %>
|
|
83
84
|
|
data/Rakefile
CHANGED
|
@@ -3,7 +3,7 @@ require 'rubygems'
|
|
|
3
3
|
require 'rake'
|
|
4
4
|
require 'echoe'
|
|
5
5
|
|
|
6
|
-
Echoe.new('constantrecord', '0.0.
|
|
6
|
+
Echoe.new('constantrecord', '0.0.2') do |p|
|
|
7
7
|
p.description = "A tiny ActiveRecord substitute for small, never changing database tables."
|
|
8
8
|
p.url = "http://github.com/ChristophPetschnig/constantrecord"
|
|
9
9
|
p.author = "Christoph Petschnig"
|
data/constantrecord.gemspec
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = %q{constantrecord}
|
|
5
|
-
s.version = "0.0.
|
|
5
|
+
s.version = "0.0.2"
|
|
6
6
|
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
|
8
8
|
s.authors = ["Christoph Petschnig"]
|
|
9
|
-
s.date = %q{2009-
|
|
9
|
+
s.date = %q{2009-04-27}
|
|
10
10
|
s.description = %q{A tiny ActiveRecord substitute for small, never changing database tables.}
|
|
11
11
|
s.email = %q{info@purevirtual.de}
|
|
12
12
|
s.extra_rdoc_files = ["lib/constantrecord.rb", "README.rdoc"]
|
data/lib/constantrecord.rb
CHANGED
|
@@ -1,252 +1,252 @@
|
|
|
1
|
-
#--
|
|
2
|
-
# Copyright (c) 2009 Christoph Petschnig
|
|
3
|
-
#
|
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
-
# a copy of this software and associated documentation files (the
|
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
-
# the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be
|
|
13
|
-
# included in all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
-
#++
|
|
23
|
-
|
|
24
|
-
module ConstantRecord
|
|
25
|
-
# ConstantRecord::Base is a tiny ActiveRecord substitute for small, never
|
|
26
|
-
# changing database tables.
|
|
27
|
-
#
|
|
28
|
-
# == Usage:
|
|
29
|
-
#
|
|
30
|
-
# class Currency < ConstantRecord::Base
|
|
31
|
-
# data 'EUR', 'USD', 'CAD', 'GBP', 'CHF'
|
|
32
|
-
# end
|
|
33
|
-
#
|
|
34
|
-
# or
|
|
35
|
-
#
|
|
36
|
-
# class MoreDetailedCurrency < ConstantRecord::Base
|
|
37
|
-
# columns :short, :description
|
|
38
|
-
# data ['EUR', 'Euro'],
|
|
39
|
-
# ['USD', 'US Dollar'],
|
|
40
|
-
# ['CAD', 'Canadian Dollar'],
|
|
41
|
-
# ['GBP', 'British Pound sterling'],
|
|
42
|
-
# ['CHF', 'Swiss franc']
|
|
43
|
-
# end
|
|
44
|
-
#
|
|
45
|
-
# To show all records in a HTML select field, use:
|
|
46
|
-
#
|
|
47
|
-
# <%= f.select :currency_id, Currency.options_for_select %>
|
|
48
|
-
#
|
|
49
|
-
class Base
|
|
50
|
-
|
|
51
|
-
private
|
|
52
|
-
attr_writer :id, :name
|
|
53
|
-
|
|
54
|
-
public
|
|
55
|
-
attr_reader :id, :name
|
|
56
|
-
|
|
57
|
-
# Set the column names of the constant table.
|
|
58
|
-
# Default is one column called `name`
|
|
59
|
-
def self.columns(*args)
|
|
60
|
-
# remove the default column name
|
|
61
|
-
undef_method :name
|
|
62
|
-
|
|
63
|
-
i = 0
|
|
64
|
-
col_ar = args.collect do |column|
|
|
65
|
-
raise TypeError.new("You can only pass Symbol or String object to #{self}::columns.") unless column.kind_of?(Symbol) || column.kind_of?(String)
|
|
66
|
-
|
|
67
|
-
class_eval do
|
|
68
|
-
private
|
|
69
|
-
attr_writer column
|
|
70
|
-
public
|
|
71
|
-
attr_reader column
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
i += 1
|
|
75
|
-
[column.to_sym, i - 1]
|
|
76
|
-
end.flatten
|
|
77
|
-
|
|
78
|
-
@columns = Hash[*col_ar]
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Set the data. Arguments must be an Array.
|
|
82
|
-
def self.data(*args)
|
|
83
|
-
@data = args.collect{|arg| arg.kind_of?(Array) ? arg : [arg]}
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Constructor; call with
|
|
87
|
-
# MyConstantRecord.new(1, 'value_of_name')
|
|
88
|
-
# or
|
|
89
|
-
# MyConstantRecord.new(1, 'values of column 1', 2, 3.333)
|
|
90
|
-
def initialize(id, *values)
|
|
91
|
-
@id = id
|
|
92
|
-
|
|
93
|
-
return if values.empty?
|
|
94
|
-
|
|
95
|
-
# set the instance variables
|
|
96
|
-
get_columns.each do |key, value|
|
|
97
|
-
instance_variable_set("@#{key}", values[value])
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Implement +find+. Warning: conditions are only supported with+:first+!
|
|
102
|
-
def self.find(*args)
|
|
103
|
-
selector = args[0]
|
|
104
|
-
|
|
105
|
-
# find might get called on constant_record_id.nil? == true
|
|
106
|
-
return nil if selector.nil?
|
|
107
|
-
|
|
108
|
-
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless selector.kind_of?(Symbol) || selector.kind_of?(Fixnum)
|
|
109
|
-
|
|
110
|
-
if selector == :first
|
|
111
|
-
conditions = args[1][:conditions]
|
|
112
|
-
|
|
113
|
-
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless conditions.kind_of?(Hash) && conditions.size == 1
|
|
114
|
-
|
|
115
|
-
compare_col_nr = get_columns[conditions.keys[0]]
|
|
116
|
-
raise "Unknown column :#{conditions.keys[0]}" unless compare_col_nr
|
|
117
|
-
|
|
118
|
-
@data.each_with_index do |datum, i|
|
|
119
|
-
return self.new(i, *datum) if datum[compare_col_nr] == conditions.values[0]
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
return nil
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# ignore conditions on :all
|
|
126
|
-
return find_all if selector == :all
|
|
127
|
-
|
|
128
|
-
# ignore conditions if id is given as the first argument
|
|
129
|
-
return find_by_id(selector) if selector.kind_of?(Fixnum)
|
|
130
|
-
|
|
131
|
-
raise "#{self}.find failed!\nArguments:#{args.inspect}"
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# Implement +count+. Warning: conditions are not supported!
|
|
135
|
-
def self.count(*args)
|
|
136
|
-
selector = args[0] || :all
|
|
137
|
-
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless selector.kind_of?(Symbol)
|
|
138
|
-
|
|
139
|
-
# ignore conditions on :all
|
|
140
|
-
return @data.size if selector == :all
|
|
141
|
-
|
|
142
|
-
raise "#{self}.find failed!\nArguments:#{args.inspect}"
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# A ConstantRecord will never be a new record
|
|
146
|
-
def new_record?
|
|
147
|
-
false
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# A ConstantRecord should never be empty
|
|
151
|
-
def empty?
|
|
152
|
-
false
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# Keep this to spot problems in integration with ActiveRecord
|
|
156
|
-
def method_missing(symbol, *args) #:nodoc:
|
|
157
|
-
p "ConstantRecord::Base#method_missing(#{symbol})"
|
|
158
|
-
super symbol, *args
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Keep this to spot problems in integration with ActiveRecord
|
|
162
|
-
def respond_to?(symbol) #:nodoc:
|
|
163
|
-
result = super(symbol)
|
|
164
|
-
p "ConstantRecord::Base#respond_to?(#{symbol}) => #{result}(#{self.class})" unless result
|
|
165
|
-
result
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Handle +find_by_xxx+ calls on the class
|
|
169
|
-
def self.method_missing(symbol, *args) #:nodoc:
|
|
170
|
-
if /^find_by_([_a-zA-Z]\w*)$/ =~ (symbol.to_s)
|
|
171
|
-
return find(:first, :conditions => {$1.to_sym => args[0]})
|
|
172
|
-
end
|
|
173
|
-
p "ConstantRecord::Base::method_missing(#{symbol})"
|
|
174
|
-
super symbol, *args
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Keep this to spot problems in integration with ActiveRecord
|
|
178
|
-
def self.respond_to?(symbol) #:nodoc:
|
|
179
|
-
result = super symbol
|
|
180
|
-
p "ConstantRecord::Base::respond_to?(#{symbol}) => #{result}(#{self.class})" unless result
|
|
181
|
-
result
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# Creates options for a select box in a form
|
|
185
|
-
# options:
|
|
186
|
-
# <tt>:display</tt> The attribute to call to display the text in the select box or
|
|
187
|
-
# a Proc object:
|
|
188
|
-
# :display => Proc.new{ |obj| "#{obj.name} (#{obj.description})" }
|
|
189
|
-
# <tt>:value</tt> The value to use for the option value. Default is the id of the record.
|
|
190
|
-
# <tt>:include_null</tt> Make an entry with the value 0 in the selectbox. Default is +false+.
|
|
191
|
-
# <tt>:null_text</tt> The text to show with on value 0. Default is '-'.
|
|
192
|
-
# <tt>:null_value</tt> The value of the null option. Default is 0.
|
|
193
|
-
def self.options_for_select(options = {})
|
|
194
|
-
display = options[:display] || get_columns.keys[0]
|
|
195
|
-
raise "#{self}.options_for_select: :display must be either Symbol or Proc." unless display.kind_of?(Symbol) ||display.kind_of?(Proc)
|
|
196
|
-
|
|
197
|
-
if display.kind_of?(Symbol)
|
|
198
|
-
display_col_nr = get_columns[display]
|
|
199
|
-
raise "Unknown column :#{conditions.keys[0]}" unless display_col_nr
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
value = options[:value] || :id
|
|
203
|
-
|
|
204
|
-
i = 0
|
|
205
|
-
result = @data.collect do |datum|
|
|
206
|
-
i += 1
|
|
207
|
-
obj = self.new(i, *datum)
|
|
208
|
-
option_show = display.kind_of?(Symbol) ? datum[display_col_nr] : display.call(obj)
|
|
209
|
-
option_value = value == :id ? i : obj.send(value)
|
|
210
|
-
|
|
211
|
-
[option_show, option_value]
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
if options[:include_null] == true
|
|
215
|
-
result.unshift [ options[:null_text] || '-', options.key?(:null_value) ? options[:null_value] : 0 ]
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
result
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
private
|
|
222
|
-
|
|
223
|
-
# Get the name of the columns or the default value
|
|
224
|
-
def self.get_columns
|
|
225
|
-
# if columns were not set, the default value is one column
|
|
226
|
-
# with the name of "name"
|
|
227
|
-
@columns || { :name => 0 }
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def get_columns #:nodoc:
|
|
231
|
-
self.class.get_columns
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
# Implementation of +find+(:all)
|
|
235
|
-
def self.find_all #:nodoc:
|
|
236
|
-
i = 0
|
|
237
|
-
@data.collect do |datum|
|
|
238
|
-
i += 1
|
|
239
|
-
self.new(i, *datum)
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# Implementation of +find+(:id)
|
|
244
|
-
def self.find_by_id(id) #:nodoc:
|
|
245
|
-
# check for valid range of selector
|
|
246
|
-
return nil if id <= 0 || id > @data.size
|
|
247
|
-
|
|
248
|
-
self.new(id, *@data[id - 1])
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
end
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2009 Christoph Petschnig
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
module ConstantRecord
|
|
25
|
+
# ConstantRecord::Base is a tiny ActiveRecord substitute for small, never
|
|
26
|
+
# changing database tables.
|
|
27
|
+
#
|
|
28
|
+
# == Usage:
|
|
29
|
+
#
|
|
30
|
+
# class Currency < ConstantRecord::Base
|
|
31
|
+
# data 'EUR', 'USD', 'CAD', 'GBP', 'CHF'
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# or
|
|
35
|
+
#
|
|
36
|
+
# class MoreDetailedCurrency < ConstantRecord::Base
|
|
37
|
+
# columns :short, :description
|
|
38
|
+
# data ['EUR', 'Euro'],
|
|
39
|
+
# ['USD', 'US Dollar'],
|
|
40
|
+
# ['CAD', 'Canadian Dollar'],
|
|
41
|
+
# ['GBP', 'British Pound sterling'],
|
|
42
|
+
# ['CHF', 'Swiss franc']
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# To show all records in a HTML select field, use:
|
|
46
|
+
#
|
|
47
|
+
# <%= f.select :currency_id, Currency.options_for_select %>
|
|
48
|
+
#
|
|
49
|
+
class Base
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
attr_writer :id, :name
|
|
53
|
+
|
|
54
|
+
public
|
|
55
|
+
attr_reader :id, :name
|
|
56
|
+
|
|
57
|
+
# Set the column names of the constant table.
|
|
58
|
+
# Default is one column called `name`
|
|
59
|
+
def self.columns(*args)
|
|
60
|
+
# remove the default column name
|
|
61
|
+
undef_method :name
|
|
62
|
+
|
|
63
|
+
i = 0
|
|
64
|
+
col_ar = args.collect do |column|
|
|
65
|
+
raise TypeError.new("You can only pass Symbol or String object to #{self}::columns.") unless column.kind_of?(Symbol) || column.kind_of?(String)
|
|
66
|
+
|
|
67
|
+
class_eval do
|
|
68
|
+
private
|
|
69
|
+
attr_writer column
|
|
70
|
+
public
|
|
71
|
+
attr_reader column
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
i += 1
|
|
75
|
+
[column.to_sym, i - 1]
|
|
76
|
+
end.flatten
|
|
77
|
+
|
|
78
|
+
@columns = Hash[*col_ar]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Set the data. Arguments must be an Array.
|
|
82
|
+
def self.data(*args)
|
|
83
|
+
@data = args.collect{|arg| arg.kind_of?(Array) ? arg : [arg]}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Constructor; call with
|
|
87
|
+
# MyConstantRecord.new(1, 'value_of_name')
|
|
88
|
+
# or
|
|
89
|
+
# MyConstantRecord.new(1, 'values of column 1', 2, 3.333)
|
|
90
|
+
def initialize(id, *values)
|
|
91
|
+
@id = id
|
|
92
|
+
|
|
93
|
+
return if values.empty?
|
|
94
|
+
|
|
95
|
+
# set the instance variables
|
|
96
|
+
get_columns.each do |key, value|
|
|
97
|
+
instance_variable_set("@#{key}", values[value])
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Implement +find+. Warning: conditions are only supported with+:first+!
|
|
102
|
+
def self.find(*args)
|
|
103
|
+
selector = args[0]
|
|
104
|
+
|
|
105
|
+
# find might get called on constant_record_id.nil? == true
|
|
106
|
+
return nil if selector.nil?
|
|
107
|
+
|
|
108
|
+
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless selector.kind_of?(Symbol) || selector.kind_of?(Fixnum)
|
|
109
|
+
|
|
110
|
+
if selector == :first
|
|
111
|
+
conditions = args[1][:conditions]
|
|
112
|
+
|
|
113
|
+
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless conditions.kind_of?(Hash) && conditions.size == 1
|
|
114
|
+
|
|
115
|
+
compare_col_nr = get_columns[conditions.keys[0]]
|
|
116
|
+
raise "Unknown column :#{conditions.keys[0]}" unless compare_col_nr
|
|
117
|
+
|
|
118
|
+
@data.each_with_index do |datum, i|
|
|
119
|
+
return self.new(i + 1, *datum) if datum[compare_col_nr] == conditions.values[0]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
return nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# ignore conditions on :all
|
|
126
|
+
return find_all if selector == :all
|
|
127
|
+
|
|
128
|
+
# ignore conditions if id is given as the first argument
|
|
129
|
+
return find_by_id(selector) if selector.kind_of?(Fixnum)
|
|
130
|
+
|
|
131
|
+
raise "#{self}.find failed!\nArguments:#{args.inspect}"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Implement +count+. Warning: conditions are not supported!
|
|
135
|
+
def self.count(*args)
|
|
136
|
+
selector = args[0] || :all
|
|
137
|
+
raise TypeError.new("#{self}.find failed!\nArguments:#{args.inspect}") unless selector.kind_of?(Symbol)
|
|
138
|
+
|
|
139
|
+
# ignore conditions on :all
|
|
140
|
+
return @data.size if selector == :all
|
|
141
|
+
|
|
142
|
+
raise "#{self}.find failed!\nArguments:#{args.inspect}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# A ConstantRecord will never be a new record
|
|
146
|
+
def new_record?
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# A ConstantRecord should never be empty
|
|
151
|
+
def empty?
|
|
152
|
+
false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Keep this to spot problems in integration with ActiveRecord
|
|
156
|
+
def method_missing(symbol, *args) #:nodoc:
|
|
157
|
+
p "ConstantRecord::Base#method_missing(#{symbol})"
|
|
158
|
+
super symbol, *args
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Keep this to spot problems in integration with ActiveRecord
|
|
162
|
+
def respond_to?(symbol) #:nodoc:
|
|
163
|
+
result = super(symbol)
|
|
164
|
+
p "ConstantRecord::Base#respond_to?(#{symbol}) => #{result}(#{self.class})" unless result
|
|
165
|
+
result
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Handle +find_by_xxx+ calls on the class
|
|
169
|
+
def self.method_missing(symbol, *args) #:nodoc:
|
|
170
|
+
if /^find_by_([_a-zA-Z]\w*)$/ =~ (symbol.to_s)
|
|
171
|
+
return find(:first, :conditions => {$1.to_sym => args[0]})
|
|
172
|
+
end
|
|
173
|
+
p "ConstantRecord::Base::method_missing(#{symbol})"
|
|
174
|
+
super symbol, *args
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Keep this to spot problems in integration with ActiveRecord
|
|
178
|
+
def self.respond_to?(symbol) #:nodoc:
|
|
179
|
+
result = super symbol
|
|
180
|
+
p "ConstantRecord::Base::respond_to?(#{symbol}) => #{result}(#{self.class})" unless result
|
|
181
|
+
result
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Creates options for a select box in a form
|
|
185
|
+
# options:
|
|
186
|
+
# <tt>:display</tt> The attribute to call to display the text in the select box or
|
|
187
|
+
# a Proc object:
|
|
188
|
+
# :display => Proc.new{ |obj| "#{obj.name} (#{obj.description})" }
|
|
189
|
+
# <tt>:value</tt> The value to use for the option value. Default is the id of the record.
|
|
190
|
+
# <tt>:include_null</tt> Make an entry with the value 0 in the selectbox. Default is +false+.
|
|
191
|
+
# <tt>:null_text</tt> The text to show with on value 0. Default is '-'.
|
|
192
|
+
# <tt>:null_value</tt> The value of the null option. Default is 0.
|
|
193
|
+
def self.options_for_select(options = {})
|
|
194
|
+
display = options[:display] || get_columns.keys[0]
|
|
195
|
+
raise "#{self}.options_for_select: :display must be either Symbol or Proc." unless display.kind_of?(Symbol) ||display.kind_of?(Proc)
|
|
196
|
+
|
|
197
|
+
if display.kind_of?(Symbol)
|
|
198
|
+
display_col_nr = get_columns[display]
|
|
199
|
+
raise "Unknown column :#{conditions.keys[0]}" unless display_col_nr
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
value = options[:value] || :id
|
|
203
|
+
|
|
204
|
+
i = 0
|
|
205
|
+
result = @data.collect do |datum|
|
|
206
|
+
i += 1
|
|
207
|
+
obj = self.new(i, *datum)
|
|
208
|
+
option_show = display.kind_of?(Symbol) ? datum[display_col_nr] : display.call(obj)
|
|
209
|
+
option_value = value == :id ? i : obj.send(value)
|
|
210
|
+
|
|
211
|
+
[option_show, option_value]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
if options[:include_null] == true
|
|
215
|
+
result.unshift [ options[:null_text] || '-', options.key?(:null_value) ? options[:null_value] : 0 ]
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
result
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
private
|
|
222
|
+
|
|
223
|
+
# Get the name of the columns or the default value
|
|
224
|
+
def self.get_columns
|
|
225
|
+
# if columns were not set, the default value is one column
|
|
226
|
+
# with the name of "name"
|
|
227
|
+
@columns || { :name => 0 }
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def get_columns #:nodoc:
|
|
231
|
+
self.class.get_columns
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Implementation of +find+(:all)
|
|
235
|
+
def self.find_all #:nodoc:
|
|
236
|
+
i = 0
|
|
237
|
+
@data.collect do |datum|
|
|
238
|
+
i += 1
|
|
239
|
+
self.new(i, *datum)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Implementation of +find+(:id)
|
|
244
|
+
def self.find_by_id(id) #:nodoc:
|
|
245
|
+
# check for valid range of selector
|
|
246
|
+
return nil if id <= 0 || id > @data.size
|
|
247
|
+
|
|
248
|
+
self.new(id, *@data[id - 1])
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
252
|
end
|
data/test/constantrecord_test.rb
CHANGED
|
@@ -22,23 +22,29 @@ end
|
|
|
22
22
|
class TestConstantRecord < Test::Unit::TestCase
|
|
23
23
|
def test_simple_finder
|
|
24
24
|
assert_equal 'Estonia', SimpleClass.find(3).name
|
|
25
|
+
assert_equal 3, SimpleClass.find(3).id
|
|
25
26
|
assert_nil SimpleClass.find(4)
|
|
26
27
|
assert_nil SimpleClass.find(0)
|
|
27
28
|
assert_nil SimpleClass.find(nil)
|
|
28
29
|
assert_equal 'Estonia', SimpleClass.find_by_name('Estonia').name
|
|
30
|
+
assert_equal 3, SimpleClass.find_by_name('Estonia').id
|
|
29
31
|
assert_raise (RuntimeError) { SimpleClass.find_by_foo('bar') }
|
|
30
32
|
assert_equal [ 'Lithuania', 'Latvia', 'Estonia' ], SimpleClass.find(:all).collect{|o| o.name}
|
|
33
|
+
assert_equal [ 1, 2, 3 ], SimpleClass.find(:all).collect{|o| o.id}
|
|
31
34
|
assert_equal 3, SimpleClass.count
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def test_simple_finder_with_custom_column_name
|
|
35
38
|
assert_equal 'Abbey Road', SimpleClass2.find(3).album
|
|
39
|
+
assert_equal 3, SimpleClass2.find(3).id
|
|
36
40
|
assert_nil SimpleClass2.find(4)
|
|
37
41
|
assert_nil SimpleClass2.find(0)
|
|
38
42
|
assert_nil SimpleClass2.find(nil)
|
|
39
43
|
assert_equal 'Sgt. Pepper', SimpleClass2.find_by_album('Sgt. Pepper').album
|
|
44
|
+
assert_equal 1, SimpleClass2.find_by_album('Sgt. Pepper').id
|
|
40
45
|
assert_raise (RuntimeError) { SimpleClass2.find_by_name('Sgt. Pepper') }
|
|
41
46
|
assert_equal [ 'Sgt. Pepper', 'Magical Mystery Tour', 'Abbey Road' ], SimpleClass2.find(:all).collect{|o| o.album}
|
|
47
|
+
assert_equal [ 1, 2, 3 ], SimpleClass2.find(:all).collect{|o| o.id}
|
|
42
48
|
assert_equal 3, SimpleClass2.count
|
|
43
49
|
end
|
|
44
50
|
|
|
@@ -48,12 +54,14 @@ class TestConstantRecord < Test::Unit::TestCase
|
|
|
48
54
|
assert 5 == chf.id && chf.short && 'Swiss franc' == chf.description
|
|
49
55
|
|
|
50
56
|
assert_equal 'Canadian Dollar', MultiColumnClass.find_by_short('CAD').description
|
|
57
|
+
assert_equal 3, MultiColumnClass.find_by_short('CAD').id
|
|
51
58
|
|
|
52
59
|
assert_nil MultiColumnClass.find(6)
|
|
53
60
|
assert_nil MultiColumnClass.find(0)
|
|
54
61
|
assert_nil MultiColumnClass.find(nil)
|
|
55
62
|
assert_raise (RuntimeError) { MultiColumnClass.find_by_name('EUR') }
|
|
56
63
|
assert_equal [ 'EUR', 'USD', 'CAD', 'GBP', 'CHF' ], MultiColumnClass.find(:all).collect{|o| o.short}
|
|
64
|
+
assert_equal [ 1, 2, 3, 4, 5 ], MultiColumnClass.find(:all).collect{|o| o.id}
|
|
57
65
|
assert_equal 5, MultiColumnClass.count
|
|
58
66
|
end
|
|
59
67
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: constantrecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christoph Petschnig
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-04-27 00:00:00 +02:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|