clevic 0.13.0.b5 → 0.13.0.b6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.13.0.b6
2
+ * switch to MrBones
3
+ * All dependencies are now gems. bsearch is a gem. So is qtbindings.
4
+ * dispense with a couple more active_support dependencies
5
+ * make tests work with minitest.
6
+ * Document attributes better
7
+ * Make sure Models based on a SQL view will work
8
+ * Fix Enumerator / Generator issues
9
+ * testing with both ruby-1.8.7 and ruby-1.9.2
10
+
1
11
  == 0.13.0.b5
2
12
  * Lots of Bug fixes
3
13
  * moved all internals to Sequel::Dataset
@@ -16,7 +26,7 @@
16
26
  * use of Dataset allows filtering in TableView to keep previous ordering,
17
27
  and filter.
18
28
 
19
- == 0.13.0.b3
29
+ == 0.13.0.b2
20
30
  * Squash various buglets as they're found.
21
31
 
22
32
  == 0.13.0
@@ -52,7 +62,7 @@
52
62
 
53
63
  == 0.11.1
54
64
  * Define views in separate classes (subclass of Clevic::View) while
55
- maintaining view definition inside the ActiveRecord::Base subclass.
65
+ maintaining view definition inside the ActiveRecord::Base subclass.
56
66
  * foreground and background color specifiers for fields
57
67
  * better handling of virtual fields
58
68
  * more tests
data/Manifest.txt CHANGED
@@ -4,6 +4,7 @@ README.txt
4
4
  Rakefile
5
5
  TODO
6
6
  bin/clevic
7
+ models/examples.rb
7
8
  models/accounts_models.rb
8
9
  models/minimal_models.rb
9
10
  models/times_models.rb
@@ -18,7 +19,6 @@ sql/accounts.sql
18
19
  sql/times.sql
19
20
  sql/times_sqlite.sql
20
21
  tasks/clevic.rake
21
- tasks/rdoc.rake
22
22
  test/test_cache_table.rb
23
23
  test/test_helper.rb
24
24
  test/test_model_index_extensions.rb
@@ -78,8 +78,6 @@ lib/clevic/qt/combo_delegate.rb
78
78
  lib/clevic/qt/browser.rb
79
79
  lib/clevic/qt/clipboard.rb
80
80
  lib/clevic/qt/text_area_delegate.rb
81
- lib/clevic/ui/browser_ui.rb
82
- lib/clevic/ui/search_dialog_ui.rb
83
81
  lib/clevic/qt.rb
84
82
  lib/clevic/many_field.rb
85
83
  lib/clevic/attribute_list.rb
data/README.txt CHANGED
@@ -2,10 +2,16 @@
2
2
 
3
3
  http://clevic.rubyforge.org
4
4
 
5
- == DESCRIPTION:
5
+ == Quick Start
6
6
 
7
- Database framework and Model/View GUI for data capture and
8
- editing of tables in a pre-existing relational DBMS. Works with Qt
7
+ For code examples, see Clevic::Examples.
8
+
9
+ For documentation, see Clevic::ModelBuilder and Clevic::Field.
10
+
11
+ == Description
12
+
13
+ Database framework and Model/View GUI for editing of table data and
14
+ data capture in a pre-existing reblational DBMS. Works with Qt
9
15
  and Java Swing. Uses SQL to do sorting and filtering wherever possible.
10
16
 
11
17
  Based on the idea of a Field, which contains information to display
@@ -20,7 +26,7 @@ Using Qt and Swing means it runs on Linux, Windows and OSX. The Qt
20
26
  code is thoroughly tested in Linux, slightly tested in Windows and OSX. Swing
21
27
  is tested in Linux and OSX.
22
28
 
23
- == FEATURES:
29
+ == Features
24
30
 
25
31
  === User Interface
26
32
 
@@ -28,20 +34,24 @@ is tested in Linux and OSX.
28
34
  * in-place combo boxes for choosing values from related tables (foreign keys)
29
35
  * distinct combo boxes to list previous values for a field
30
36
  * display read-only fields from related tables
31
- * Recursive Filter by current field
37
+ * Multi-level filter by current field
32
38
  * search by field contents
33
- * cut and paste in CSV and paste from HTML in the Java framework.
39
+ * cut and paste in CSV, and paste from HTML in the Java framework.
34
40
 
35
41
  === Shortcuts:
36
42
 
37
- * Ctrl-' for ditto (copy value from previous record)
43
+ * Ctrl-<tt>'</tt> for ditto (copy value from previous record)
38
44
  * Ctrl-; for insert current date
39
- * Ctrl-] for copy previous record, one field right
40
- * Ctrl-[ for copy previous record, one field left
45
+ * Ctrl-] for copy from previous record, one field right
46
+ * Ctrl-[ for copy from previous record, one field left
41
47
  * Ctrl-f to find a record
42
48
  * Ctrl-l to add a filter (by current selection)
43
49
  * Ctrl-k to remove a filter
44
50
  * cursor keys, PgUp PgDown etc for movement
51
+ * shift with movement keys to extend selection
52
+ * Ctrl-Tab and Ctrl-Shift-Tab to move next/previous table views
53
+ * F2 to edit a field
54
+ * F4 to display a combo box for a field, where appropriate
45
55
 
46
56
  === Model definition:
47
57
 
@@ -51,13 +61,6 @@ that includes the Clevic::Record module will provide a minimally functional UI.
51
61
  Beyond that, the framework provides a DSL for defining more complex and useful behaviour
52
62
  (see Clevic::ModelBuilder).
53
63
 
54
- === Examples
55
-
56
- In the models/ subdirectory, start with minimal_models.rb. account_models.rb
57
- and times_models.rb provide definitions for real-world examples. Associated
58
- SQL schemas are in the sql subdirectory. For implementation and more extensive
59
- comments, see Clevic::ModelBuilder.
60
-
61
64
  === Framework
62
65
 
63
66
  * uses Sequel for data access.
@@ -67,44 +70,29 @@ comments, see Clevic::ModelBuilder.
67
70
  * leverages SQL whenever possible to handle large datasets, sorting, filtering
68
71
  etc. So it's probably not suitable for talking to a remote db across a slow link.
69
72
 
70
- == PROBLEMS:
73
+ == Problems
71
74
 
72
75
  There are some tests for algorithmic code, but Clevic needs a comprehensive testing framework.
73
76
 
74
- == SYNOPSIS:
77
+ == Synopsis
75
78
 
76
- clevic [ --qt | --swing ] model_definition_file.rb
79
+ clevic model_definition_file.rb
77
80
 
78
- == REQUIREMENTS:
79
-
80
- === Gems
81
- * Sequel
82
- * fastercsv
83
- * qtext
84
- * hashery (for ruby-1.8.x)
85
- * qtbindings
86
- * gather
87
-
88
- === Libraries
89
- * qtruby4 >= 2.0.3
90
- * bsearch (http://0xcc.net/ruby-bsearch)
81
+ == Requirements
82
+
91
83
  * db driver (ie pg)
92
84
  * rdbms (ie postgres)
93
85
 
94
- == INSTALL:
86
+ == Install
95
87
 
96
- Get bsearch from http://0xcc.net/ruby-bsearch
97
-
98
- Install qt bindings from https://github.com/ryanmelt/qtbindings
99
-
100
- sudo gem install
88
+ sudo gem install clevic
101
89
 
102
- == THANKS:
90
+ == Thanks
103
91
 
104
92
  * Michelle Riley for help debugging under windows
105
93
  * Jacob Buys for pointing out the qtbindings gem
106
94
 
107
- == LICENSE:
95
+ == License
108
96
 
109
97
  (The GPL-2 License)
110
98
 
data/Rakefile CHANGED
@@ -1,35 +1,73 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- require File.dirname(__FILE__) + '/lib/clevic/version.rb'
3
-
4
- # Generate all the Rake tasks
5
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
- $hoe = Hoe.new('clevic', Clevic::VERSION::STRING) do |p|
7
- p.developer('John Anderson', 'panic@semiosix.com')
8
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
- p.rubyforge_name = p.name # TODO this is default value
10
- p.description = "SQL table GUI with Qt / Java Swing and Sequel"
11
- p.extra_deps = [
12
- ['activesupport','>= 2.0.2'],
13
- ['fastercsv', '>=1.2.3'],
14
- ['gather', '>=0.0.6'],
15
- ['qtext', '>=0.6.6'],
16
- ['hashery', '>=1.3.0'],
17
- ['andand', '>= 1.3.0'],
18
- ['sequel', '>= 3.8.0'],
19
- ['hpricot', '>= 0.8.1'],
20
- ['io-like', '>= 0.3.0'],
21
- #['qtbindings', '>=4.6.3']
22
- # bsearch can't be installed from gems
23
- ]
24
- p.extra_dev_deps = [
25
- ['newgem', ">= #{::Newgem::VERSION}"]
26
- ]
27
-
28
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
29
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
30
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
31
- p.rsync_args = '-av --delete --ignore-errors'
1
+ #~ %w[rake rake/clean fileutils].each { |f| require f }
2
+
3
+ begin
4
+ require 'bones'
5
+ rescue LoadError
6
+ abort '### Please install the "bones" gem ###'
7
+ end
8
+
9
+ #~ task :default => 'test:run'
10
+ #~ task 'gem:release' => 'test:run'
11
+
12
+ ensure_in_path 'lib'
13
+ require 'clevic/version.rb'
14
+
15
+ # rake bones:help |less
16
+
17
+ Bones do
18
+ name 'clevic'
19
+ authors 'John Anderson'
20
+ email 'panic@semiosix.com'
21
+ url 'http://clevic.rubyforge.org'
22
+ version Clevic::VERSION::STRING
23
+ description "SQL table GUI with Qt / Java Swing and Sequel"
24
+
25
+ gem.need_tar false
26
+
27
+ depend_on 'fastercsv', '>=1.2.3'
28
+ depend_on 'gather', '>=0.0.6'
29
+ depend_on 'andand', '>= 1.3.0'
30
+ depend_on 'sequel', '>= 3.8.0'
31
+ depend_on 'bsearch', '>=1.5.0'
32
+ # for html paste parsing
33
+ depend_on 'hpricot', '>= 0.8.1'
34
+
35
+ # for 1.8
36
+ depend_on 'hashery', '>=1.3.0'
37
+
38
+ # for JRuby clipboard handling
39
+ depend_on 'io-like', '>= 0.3.0'
40
+
41
+ # for Qt
42
+ depend_on 'qtbindings', '>=4.6.3'
43
+ depend_on 'qtext', '>=0.6.7'
44
+
45
+ depend_on 'test-unit', :development => true
46
+ depend_on 'shoulda', :development => true
47
+ depend_on 'faker', :development => true
48
+
49
+ # read file list from Manifest.txt
50
+ gem.files File.new('Manifest.txt').to_a.map( &:chomp )
51
+
52
+ # List of files to generate rdoc from
53
+ # Not the same as the rdoc -i which is list of files
54
+ # to search for include directives
55
+ rdoc.include %w{README.txt ^lib/clevic/.*\.rb$ models/examples.rb History.txt TODO}
56
+
57
+ # List of Regexs to exclude from rdoc processing
58
+ rdoc.exclude %w{^pkg.*}
59
+
60
+ # Include URL for git browser in rdoc output
61
+ rdoc.opts %w{-W http://gitweb.semiosix.com/gitweb.cgi?p=clevic;a=blob;f=%s;hb=HEAD}
62
+
63
+ rdoc.main 'README.txt'
64
+ #~ rdoc.external true
32
65
  end
33
66
 
34
- require 'newgem/tasks' # load /tasks/*.rake
35
- Dir['tasks/**/*.rake'].each { |t| load t }
67
+ #~ p.clean_globs |= %w[**/.DS_Store tmp *.log]
68
+ #~ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
69
+ #~ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
70
+ #~ p.rsync_args = '-av --delete --ignore-errors'
71
+ #~ end
72
+
73
+ #~ Dir['tasks/**/*.rake'].each { |t| load t }
data/TODO CHANGED
@@ -1,3 +1,8 @@
1
+ sorting by header:
2
+ - See void QAbstractItemModel::sort ( int column, Qt::SortOrder order = Qt::AscendingOrder )
3
+ - layoutChanged
4
+
5
+ change instance_methods.include? to method_defined?
1
6
  override_next_index broken again, on ditto
2
7
  Sort out the whole /bin/clevic vs gem 'clevic', '~> 0.12.0' thing.
3
8
  Meta should be related to ModelColumn somehow. Which is pretty messy itself.
@@ -31,8 +36,6 @@ has_many :through
31
36
  composed_of & aggregates
32
37
  generate schema from definition? See rubyforge
33
38
  Ctrl-PgDn to last row in this column. Also extend selection
34
- sorting by header. See void QAbstractItemModel::sort ( int column, Qt::SortOrder order = Qt::AscendingOrder )
35
- - layoutChanged
36
39
 
37
40
  undo
38
41
  - could possibly handle this in the TableModel
data/bin/clevic CHANGED
@@ -49,6 +49,7 @@ if RUBY_PLATFORM == 'java'
49
49
  else
50
50
  require 'clevic/qt'
51
51
  end
52
+ require 'clevic'
52
53
 
53
54
  if $options[:debug]
54
55
  require 'pp'
data/lib/clevic.rb CHANGED
@@ -8,8 +8,15 @@ end
8
8
 
9
9
  # TODO should this really be here?
10
10
  # There are other inflection gems.
11
- # JRuby-1.5.2 raises exception if this require has a .rb on the
12
- require 'active_support/inflector'
11
+
12
+ # for camelize and friends
13
+ # TODO JRuby-1.5.2 raises exception if this require has a .rb on the
14
+ require 'sequel/core'
15
+ require 'sequel/extensions/inflector'
16
+
17
+ # for demodulize, tableize, humanize
18
+ require 'sequel'
19
+ require 'sequel/extensions/inflector'
13
20
 
14
21
  require 'clevic/framework'
15
22
  require 'clevic/sequel_length_validation.rb'
@@ -74,10 +74,10 @@ def Range
74
74
  end
75
75
  end
76
76
 
77
- # workaround for the date freeze issue, if it exists
78
77
  begin
79
78
  Date.new.freeze.to_s
80
79
  rescue TypeError
80
+ # Workaround for the date freeze issue, if it exists.
81
81
  class Date
82
82
  def freeze
83
83
  self
data/lib/clevic/field.rb CHANGED
@@ -7,12 +7,11 @@ require 'clevic/many_field.rb'
7
7
  module Clevic
8
8
 
9
9
  =begin rdoc
10
+
10
11
  This defines a field in the UI, and how it hooks up to a field in the DB.
11
12
 
12
- Many attributes are DSL-style accessors, where the value can be
13
- set with either an assignment or by passing a parameter. Unfortunately
14
- rdoc seems to have lost the ability to display these nicely. Anyway, here's
15
- an example
13
+ Some attributes are DSL-style accessors, where the value can be
14
+ set with either an assignment or by passing a parameter. For example:
16
15
 
17
16
  property :ixnay
18
17
 
@@ -36,17 +35,10 @@ Generally properties are for options that can be passed to the field creation
36
35
  method in ModelBuilder, whereas ruby attributes are for the internal workings.
37
36
 
38
37
  #--
39
- TODO decide whether value_for type methods take an entity and do_something methods
40
- take a value.
41
-
42
- TODO the xxx_for methods are in here because their return values don't change
43
- by entity. Well, maybe sometimes they do. Anyway, need to find a better location
44
- for these and a better caching strategy.
45
-
46
- TODO this class is a bit confused about whether it handles metadata or record data, or both.
47
-
48
- TODO meta needs to handle virtual fields better.
38
+ Yes, the blank line before class Field is really necessary.
39
+ And so it the #-- above.
49
40
  =end
41
+
50
42
  class Field
51
43
  # For defining properties
52
44
  include Gather
@@ -55,6 +47,7 @@ class Field
55
47
  include GenericFormat
56
48
 
57
49
  ##
50
+ # :attr:
58
51
  # The value to be displayed after being optionally format-ed
59
52
  #
60
53
  # Takes a String, a Symbol, or a Proc.
@@ -71,20 +64,24 @@ class Field
71
64
  property :display
72
65
 
73
66
  ##
67
+ # :attr:
74
68
  # The label to be displayed in the column headings. Defaults to the humanised field name.
75
69
  property :label
76
70
 
77
71
  ##
72
+ # :attr:
78
73
  # One of the alignment specifiers - :left, :centre, :right or :justified.
79
74
  # Defaults to right for numeric fields, centre for boolean, and left for
80
75
  # other values.
81
76
  property :alignment
82
77
 
83
78
  ##
79
+ # :attr:
84
80
  # something to do with the icon that Qt displays. Not implemented yet.
85
81
  property :decoration
86
82
 
87
83
  ##
84
+ # :attr:
88
85
  # This defines how to format the value returned by :display. It takes a string or a Proc.
89
86
  # Generally the string is something
90
87
  # that can be understood by strftime (for time and date fields) or understood
@@ -93,6 +90,7 @@ class Field
93
90
  property :format
94
91
 
95
92
  ##
93
+ # :attr:
96
94
  # This is just like format, except that it's used to format the value just
97
95
  # before it's edited. A good use of this is to display dates with a 2-digit year
98
96
  # but edit them with a 4 digit year.
@@ -100,10 +98,12 @@ class Field
100
98
  property :edit_format
101
99
 
102
100
  ##
101
+ # :attr:
103
102
  # Whether the field is currently visible or not.
104
103
  property :visible
105
104
 
106
105
  ##
106
+ # :attr:
107
107
  # Sample is used if the programmer wishes to provide a value (that will be converted
108
108
  # using to_s) that can be used
109
109
  # as the basis for calculating the width of the field. By default this will be
@@ -113,10 +113,12 @@ class Field
113
113
  property :sample
114
114
 
115
115
  ##
116
+ # :attr:
116
117
  # Takes a boolean. Set the field to read-only.
117
118
  property :read_only
118
119
 
119
120
  ##
121
+ # :attr:
120
122
  # The foreground and background colors.
121
123
  # Can take a Proc, a string, or a symbol.
122
124
  # - A Proc is called with an entity
@@ -128,6 +130,7 @@ class Field
128
130
  property :foreground, :background
129
131
 
130
132
  ##
133
+ # :attr:
131
134
  # Can take a Proc, a string, or a symbol.
132
135
  # - A Proc is called with an entity
133
136
  # - A String is treated as a constant
@@ -135,6 +138,7 @@ class Field
135
138
  property :tooltip
136
139
 
137
140
  ##
141
+ # :attr:
138
142
  # An Enumerable of allowed values for restricted fields. If each yields
139
143
  # two values (like it does for a Hash), the
140
144
  # first will be stored in the db, and the second displayed in the UI.
@@ -142,6 +146,7 @@ class Field
142
146
  property :set
143
147
 
144
148
  ##
149
+ # :attr:
145
150
  # When this is true, only the values in the combo may be entered.
146
151
  # Otherwise the text-entry part of the combo can be used to enter
147
152
  # non-listed values. Default is true if a set is explicitly specified.
@@ -149,6 +154,7 @@ class Field
149
154
  property :restricted
150
155
 
151
156
  ##
157
+ # :attr:
152
158
  # Only for the distinct field type. The values will be sorted either with the
153
159
  # most used values first (:frequency => true) or in
154
160
  # alphabetical order (:description => true).
@@ -156,18 +162,21 @@ class Field
156
162
  property :frequency, :description
157
163
 
158
164
  ##
165
+ # :attr:
159
166
  # Default value for this field for new records.
160
167
  # Can be a Proc or a value. A value will just be
161
168
  # set, a proc will be executed with the entity as a parameter.
162
169
  property :default
163
170
 
164
171
  ##
172
+ # :attr:
165
173
  # The property used for finding the field, ie by TableModel#field_column.
166
174
  # Defaults to the attribute. If there are several display fields based on
167
175
  # one db field, their attribute will be the same, but their id must be different.
168
176
  property :id
169
177
 
170
178
  ##
179
+ # :attr:
171
180
  # Called when the data in this field changes.
172
181
  # Either a proc( clevic_view, table_view, model_index ) or a symbol
173
182
  # for a method( view, model_index ) on the Clevic::View object.
@@ -215,9 +224,9 @@ class Field
215
224
  # for this field using whatever GUI toolkit is selected
216
225
  attr_accessor :delegate
217
226
 
218
- # The attribute on the AR entity that forms the basis for this field.
227
+ # The attribute on the entity that forms the basis for this field.
219
228
  # Accessing the returned attribute (using send, or the [] method on an entity)
220
- # will give a simple value, or another AR entity in the case of relational fields.
229
+ # will give a simple value, or another entity in the case of relational fields.
221
230
  # In other words, this is *not* the same as the name of the field in the DB, which
222
231
  # would normally have an _id suffix for relationships.
223
232
  attr_accessor :attribute
@@ -236,12 +245,16 @@ class Field
236
245
  raise "attribute #{attribute.inspect} must be a symbol"
237
246
  end
238
247
 
239
- unless ( entity_class.is_a?( Clevic.base_entity_class ) and entity_class.has_attribute?( attribute ) ) or entity_class.instance_methods.include?( attribute.to_s )
240
- msg = <<EOF
241
- #{attribute} not found in #{entity_class.name}. Possibilities are:
242
- #{entity_class.attribute_names.join("\n")}
248
+ unless entity_class.ancestors.include?( Clevic.base_entity_class )
249
+ raise "#{entity_class} is not a Clevic.base_entity_class: #{Clevic.base_entity_class}"
250
+ end
251
+
252
+ # TODO this comes down to method_defined, really
253
+ unless entity_class.has_attribute?( attribute ) or entity_class.method_defined?( attribute )
254
+ raise <<EOF
255
+ #{attribute.inspect} not found in #{entity_class.name}. Possibilities are:
256
+ #{entity_class.attribute_names.inspect}
243
257
  EOF
244
- raise msg
245
258
  end
246
259
 
247
260
  # instance variables
@@ -303,7 +316,7 @@ EOF
303
316
  meta.andand.association?
304
317
  end
305
318
 
306
- # ModelColumn object
319
+ # Clevic::ModelColumn object
307
320
  def meta
308
321
  entity_class.meta[attribute]
309
322
  end
@@ -320,14 +333,15 @@ EOF
320
333
  [attribute.to_s, path].compact.join('.')
321
334
  end
322
335
 
323
- # return the class object of a related class if this is a relational
324
- # field, otherwise nil
336
+ # Return the class object of a related class if this is a relational
337
+ # field, otherwise nil.
325
338
  def related_class
326
339
  return nil unless association? && entity_class.meta.has_key?( attribute )
327
340
  @related_class ||= eval( entity_class.meta[attribute].class_name || attribute.to_s.classify )
328
341
  end
329
342
 
330
343
  # return an array of the various attribute parts
344
+ # TODO not used much. Deprecate and remove.
331
345
  def attribute_path
332
346
  pieces = [ attribute.to_s ]
333
347
  pieces.concat( display.to_s.split( '.' ) ) unless display.is_a? Proc
@@ -339,17 +353,20 @@ EOF
339
353
  @read_only || false
340
354
  end
341
355
 
342
- # Called by Clevic::Model to format the display value.
356
+ # Called by Clevic::FieldValuer (and others) to format the display value.
343
357
  def do_format( value )
344
358
  do_generic_format( format, value )
345
359
  end
346
360
 
347
- # Called by Clevic::Model to format the edit value.
361
+ # Called by Clevic::FieldValuer to format the field to a string value
362
+ # that can be used for editing.
348
363
  def do_edit_format( value )
349
364
  do_generic_format( edit_format, value )
350
365
  end
351
366
 
352
367
  # Set or return a sample for the field which can be used to size the UI field widget.
368
+ # If this is called as an accessor, and there is no value yet, a Clevic::Sampler
369
+ # instance is created to compute a sample.
353
370
  def sample( *args )
354
371
  if !args.empty?
355
372
  @sample = args.first
@@ -426,8 +443,12 @@ EOF
426
443
  end
427
444
  end
428
445
 
446
+ def to_s
447
+ "#{entity_class}.#{id}"
448
+ end
449
+
429
450
  def inspect
430
- "#<Clevic::Field id=#{id.inspect}>"
451
+ "#<Clevic::Field #{entity_class} id=#{id} attribute=#{attribute}>"
431
452
  end
432
453
 
433
454
  protected
@@ -494,10 +515,11 @@ protected
494
515
  end
495
516
 
496
517
  # try to find a sensible display method
518
+ # TODO this code shows up in the default UI builder as well.
497
519
  def default_display!
498
520
  candidates = %W{#{entity_class.name.downcase} name title username to_s}
499
521
  @display ||= candidates.find do |m|
500
- related_class.column_names.include?( m ) || related_class.instance_methods.include?( m )
522
+ related_class.column_names.include?( m ) || related_class.method_defined?( m )
501
523
  end || raise( "Can't find one of #{candidates.inspect} in #{related_class.name}" )
502
524
  end
503
525