hobo_fields 1.3.0.RC4 → 1.3.0.pre10
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/CHANGES.txt +3 -3
- data/Rakefile +1 -3
- data/VERSION +1 -1
- data/bin/hobofields +3 -3
- data/hobo_fields.gemspec +1 -1
- data/lib/generators/hobo/migration/migrator.rb +1 -7
- data/lib/hobo_fields/model/index_spec.rb +1 -11
- data/lib/hobo_fields/model.rb +7 -14
- data/lib/hobo_fields/sanitize_html.rb +2 -2
- data/lib/hobo_fields/types/email_address.rb +1 -3
- data/lib/hobo_fields/types/enum_string.rb +1 -1
- data/lib/hobo_fields/types/lifecycle_state.rb +2 -2
- data/lib/hobo_fields/types/password_string.rb +1 -1
- data/lib/hobo_fields/types/raw_html_string.rb +1 -1
- data/lib/hobo_fields/types/raw_markdown_string.rb +1 -1
- data/lib/hobo_fields/types/serialized_object.rb +1 -1
- data/lib/hobo_fields/types/text.rb +3 -2
- data/lib/hobo_fields/types/textile_string.rb +1 -1
- data/lib/hobo_fields.rb +11 -8
- data/test/migration_generator_comments.rdoctest +2 -2
- data/test/prepare_testapp.rb +2 -3
- data/test/rich_types.rdoctest +25 -166
- metadata +58 -13
data/CHANGES.txt
CHANGED
@@ -15,12 +15,12 @@
|
|
15
15
|
|
16
16
|
EnumString -- now defines constants on the class for each value in
|
17
17
|
the enum
|
18
|
-
|
18
|
+
|
19
19
|
Also, won't define an is_foo? method if that already exists
|
20
20
|
|
21
21
|
Removing HoboFields::Percentage -- this is better handled as an
|
22
22
|
application specific type
|
23
|
-
|
23
|
+
|
24
24
|
For example, is a percentage an fixnum or a float? Is 101% valid
|
25
25
|
or invalid?
|
26
26
|
|
@@ -28,7 +28,7 @@
|
|
28
28
|
|
29
29
|
*Breaking Change* EnumString: Change to automatically defined
|
30
30
|
class methods on EnumString classes
|
31
|
-
|
31
|
+
|
32
32
|
It used to be that if you did EnumString.for(:foo, :baa), your
|
33
33
|
class had methods foo, baa and the instance got methods foo?
|
34
34
|
and baa?. There was a big problem with name clashes with other
|
data/Rakefile
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'active_record'
|
3
|
-
require 'tmpdir'
|
4
|
-
|
5
3
|
ActiveRecord::ActiveRecordError # hack for https://rails.lighthouseapp.com/projects/8994/tickets/2577-when-using-activerecordassociations-outside-of-rails-a-nameerror-is-thrown
|
6
4
|
|
7
5
|
RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']).sub(/.*\s.*/m, '"\&"')
|
@@ -13,7 +11,7 @@ require 'hobo_support'
|
|
13
11
|
require 'hobo_fields'
|
14
12
|
|
15
13
|
GEM_ROOT = File.expand_path('../', __FILE__)
|
16
|
-
TESTAPP_PATH =
|
14
|
+
TESTAPP_PATH = '/tmp/hobo_fields_testapp'
|
17
15
|
BIN = File.expand_path('../bin/hobofields', __FILE__)
|
18
16
|
require 'hobo_support/common_tasks'
|
19
17
|
include HoboSupport::CommonTasks
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.0.
|
1
|
+
1.3.0.pre10
|
data/bin/hobofields
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
-
if ENV["
|
5
|
-
dev_root = File.expand_path ENV["
|
4
|
+
if ENV["HOBO_DEV_ROOT"]
|
5
|
+
dev_root = File.expand_path ENV["HOBO_DEV_ROOT"], FileUtils.pwd
|
6
6
|
$:.unshift "#{dev_root}/hobo_support/lib"
|
7
7
|
else
|
8
8
|
require 'rubygems'
|
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
require 'hobo_support/command'
|
13
13
|
rescue LoadError
|
14
14
|
puts "The 'hobo_support' gem is not installed.
|
15
|
-
You probably need to set the
|
15
|
+
You probably need to set the HOBO_DEV_ROOT environment variable to the local repository path."
|
16
16
|
exit
|
17
17
|
end
|
18
18
|
|
data/hobo_fields.gemspec
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
name = File.basename( __FILE__, '.gemspec' )
|
2
2
|
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
3
|
-
require 'date'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
|
@@ -11,6 +10,7 @@ Gem::Specification.new do |s|
|
|
11
10
|
s.summary = 'Rich field types and migration generator for Rails'
|
12
11
|
s.description = 'Rich field types and migration generator for Rails'
|
13
12
|
|
13
|
+
s.add_runtime_dependency('rails', [">= 3.0.0"])
|
14
14
|
s.add_runtime_dependency('hobo_support', ["= #{version}"])
|
15
15
|
s.add_development_dependency('rubydoctest', [">= 0"])
|
16
16
|
s.add_development_dependency('redcloth', [">= 0"]) # for testing rich types
|
@@ -18,10 +18,6 @@ module Generators
|
|
18
18
|
self.join_table
|
19
19
|
end
|
20
20
|
|
21
|
-
def table_exists?
|
22
|
-
ActiveRecord::Migration.table_exists? table_name
|
23
|
-
end
|
24
|
-
|
25
21
|
def field_specs
|
26
22
|
i = 0
|
27
23
|
foreign_keys.inject({}) do |h, v|
|
@@ -130,7 +126,7 @@ module Generators
|
|
130
126
|
all_models = table_model_classes
|
131
127
|
hobo_models = all_models.select { |m| m.try.include_in_migration && m.name.underscore.not_in?(ignore_model_names) }
|
132
128
|
non_hobo_models = all_models - hobo_models
|
133
|
-
db_tables = connection.tables - Migrator.ignore_tables.*.to_s - non_hobo_models
|
129
|
+
db_tables = connection.tables - Migrator.ignore_tables.*.to_s - non_hobo_models.*.table_name
|
134
130
|
[hobo_models, db_tables]
|
135
131
|
end
|
136
132
|
|
@@ -391,8 +387,6 @@ module Generators
|
|
391
387
|
def drop_index(table, name)
|
392
388
|
# see https://hobo.lighthouseapp.com/projects/8324/tickets/566
|
393
389
|
# for why the rescue exists
|
394
|
-
max_length = connection.index_name_length
|
395
|
-
name = name[0,max_length] if name.length > max_length
|
396
390
|
"remove_index :#{table}, :name => :#{name} rescue ActiveRecord::StatementInvalid"
|
397
391
|
end
|
398
392
|
|
@@ -28,17 +28,7 @@ module HoboFields
|
|
28
28
|
def to_add_statement(new_table_name)
|
29
29
|
r = "add_index :#{new_table_name}, #{fields.*.to_sym.inspect}"
|
30
30
|
r += ", :unique => true" if unique
|
31
|
-
|
32
|
-
check_name = @model.connection.index_name(self.table, :column => self.fields)
|
33
|
-
else
|
34
|
-
check_name = name
|
35
|
-
end
|
36
|
-
if check_name.length > @model.connection.index_name_length
|
37
|
-
r += ", :name => '#{name[0,@model.connection.index_name_length]}'"
|
38
|
-
$stderr.puts("WARNING: index name #{check_name} too long, trimming")
|
39
|
-
else
|
40
|
-
r += ", :name => '#{name}'" unless default_name?
|
41
|
-
end
|
31
|
+
r += ", :name => '#{name}'" unless default_name?
|
42
32
|
r
|
43
33
|
end
|
44
34
|
|
data/lib/hobo_fields/model.rb
CHANGED
@@ -22,16 +22,13 @@ module HoboFields
|
|
22
22
|
inheriting_cattr_reader :index_specs => []
|
23
23
|
inheriting_cattr_reader :ignore_indexes => []
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
fields do |f|
|
29
|
-
f.field(inheritance_column, :string)
|
30
|
-
end
|
31
|
-
index(inheritance_column)
|
32
|
-
super
|
25
|
+
def self.inherited(klass)
|
26
|
+
fields do |f|
|
27
|
+
f.field(inheritance_column, :string)
|
33
28
|
end
|
34
|
-
|
29
|
+
index(inheritance_column)
|
30
|
+
super
|
31
|
+
end
|
35
32
|
|
36
33
|
def self.index(fields, options = {})
|
37
34
|
# don't double-index fields
|
@@ -170,11 +167,7 @@ module HoboFields
|
|
170
167
|
|
171
168
|
def self.add_index_for_field(name, args, options)
|
172
169
|
to_name = options.delete(:index)
|
173
|
-
unless to_name
|
174
|
-
# passing :unique => true doesn't do anything without an index
|
175
|
-
Rails.logger.error('ERROR: passing :unique => true without :index => true does nothing. Use :unique instead.') if options[:unique]
|
176
|
-
return
|
177
|
-
end
|
170
|
+
return unless to_name
|
178
171
|
index_opts = {}
|
179
172
|
index_opts[:unique] = :unique.in?(args) || options.delete(:unique)
|
180
173
|
# support :index => true declaration
|
@@ -4,10 +4,10 @@ module HoboFields
|
|
4
4
|
|
5
5
|
PERMITTED_TAGS = %w(a abbr acronym address b bdo big blockquote br caption center cite code colgroup dd del dfn dir
|
6
6
|
div dl dt em fieldset font h1 h2 h3 h4 h5 h6 i img ins kbd label legend li map menu ol optgroup
|
7
|
-
option p pre q s samp select small span strike strong sub sup
|
7
|
+
option p pre q s samp select small span strike strong sub sup tbody td textarea tfoot
|
8
8
|
th thead tr tt u ul var)
|
9
9
|
|
10
|
-
PERMITTED_ATTRIBUTES = %w(href title class style align name src label target
|
10
|
+
PERMITTED_ATTRIBUTES = %w(href title class style align name src label target)
|
11
11
|
|
12
12
|
class Helper
|
13
13
|
include ActionView::Helpers::SanitizeHelper
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/string/output_safety'
|
2
|
-
|
3
1
|
module HoboFields
|
4
2
|
module Types
|
5
3
|
class EmailAddress < String
|
@@ -15,7 +13,7 @@ module HoboFields
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def to_html(xmldoctype = true)
|
18
|
-
|
16
|
+
self.sub('@', " at ").gsub('.', ' dot ')
|
19
17
|
end
|
20
18
|
|
21
19
|
HoboFields.register_type(:email_address, self)
|
@@ -5,11 +5,11 @@ module HoboFields
|
|
5
5
|
COLUMN_TYPE = :string
|
6
6
|
|
7
7
|
class << self
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :table_name
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_html(xmldoctype = true)
|
12
|
-
I18n.t("
|
12
|
+
I18n.t("#{self.class.table_name}.states.#{self}", :default => self)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
-
require 'active_support/core_ext/string/output_safety'
|
2
1
|
module HoboFields
|
3
2
|
module Types
|
4
3
|
class Text < String
|
5
4
|
|
5
|
+
HTML_ESCAPE = { '&' => '&', '"' => '"', '>' => '>', '<' => '<' }
|
6
|
+
|
6
7
|
COLUMN_TYPE = :text
|
7
8
|
|
8
9
|
def to_html(xmldoctype = true)
|
9
|
-
|
10
|
+
gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }.gsub("\n", "<br#{xmldoctype ? ' /' : ''}>\n")
|
10
11
|
end
|
11
12
|
|
12
13
|
HoboFields.register_type(:text, self)
|
data/lib/hobo_fields.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'hobo_support'
|
2
2
|
|
3
3
|
ActiveSupport::Dependencies.autoload_paths |= [ File.dirname(__FILE__) ]
|
4
|
-
ActiveSupport::Dependencies.autoload_once_paths |= [ File.dirname(__FILE__) ]
|
5
4
|
|
6
5
|
module Hobo
|
7
6
|
# Empty class to represent the boolean type.
|
@@ -11,15 +10,13 @@ end
|
|
11
10
|
module HoboFields
|
12
11
|
|
13
12
|
VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
|
14
|
-
@@root = Pathname.new File.expand_path('../..', __FILE__)
|
15
|
-
def self.root; @@root; end
|
16
13
|
|
17
14
|
extend self
|
18
15
|
|
19
16
|
PLAIN_TYPES = {
|
20
17
|
:boolean => Hobo::Boolean,
|
21
18
|
:date => Date,
|
22
|
-
:datetime => ActiveSupport::TimeWithZone,
|
19
|
+
:datetime => (defined?(ActiveSupport::TimeWithZone) ? ActiveSupport::TimeWithZone : Time),
|
23
20
|
:time => Time,
|
24
21
|
:integer => Integer,
|
25
22
|
:decimal => BigDecimal,
|
@@ -47,7 +44,9 @@ module HoboFields
|
|
47
44
|
}
|
48
45
|
|
49
46
|
@field_types = PLAIN_TYPES.with_indifferent_access
|
47
|
+
|
50
48
|
@never_wrap_types = Set.new([NilClass, Hobo::Boolean, TrueClass, FalseClass])
|
49
|
+
|
51
50
|
attr_reader :field_types
|
52
51
|
|
53
52
|
def to_class(type)
|
@@ -59,32 +58,36 @@ module HoboFields
|
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
61
|
+
|
62
62
|
def to_name(type)
|
63
63
|
field_types.key(type) || ALIAS_TYPES[type]
|
64
64
|
end
|
65
65
|
|
66
|
+
|
66
67
|
def can_wrap?(type, val)
|
67
68
|
col_type = type::COLUMN_TYPE
|
68
69
|
return false if val.blank? && (col_type == :integer || col_type == :float || col_type == :decimal)
|
69
70
|
klass = Object.instance_method(:class).bind(val).call # Make sure we get the *real* class
|
70
|
-
|
71
|
-
|
72
|
-
init_method.owner != Object.instance_method(:initialize).owner &&
|
73
|
-
!@never_wrap_types.any? { |c| klass <= c }
|
71
|
+
arity = type.instance_method(:initialize).arity
|
72
|
+
(arity == 1 || arity == -1) && !@never_wrap_types.any? { |c| klass <= c }
|
74
73
|
end
|
75
74
|
|
75
|
+
|
76
76
|
def never_wrap(type)
|
77
77
|
@never_wrap_types << type
|
78
78
|
end
|
79
79
|
|
80
|
+
|
80
81
|
def register_type(name, klass)
|
81
82
|
field_types[name] = klass
|
82
83
|
end
|
83
84
|
|
85
|
+
|
84
86
|
def plain_type?(type_name)
|
85
87
|
type_name.in?(PLAIN_TYPES)
|
86
88
|
end
|
87
89
|
|
90
|
+
|
88
91
|
def standard_class(name)
|
89
92
|
class_name = STANDARD_TYPES[name]
|
90
93
|
"HoboFields::Types::#{class_name}".constantize if class_name
|
@@ -5,7 +5,7 @@ Our test requires to prepare the testapp for a different environment:
|
|
5
5
|
|
6
6
|
doctest_require: ENV["RAILS_ENV"] = 'mysql_test'; 'prepare_testapp'
|
7
7
|
|
8
|
-
>> system "cd #{
|
8
|
+
>> system "cd #{TEST_APP_ROOT} && rake db:setup"
|
9
9
|
=> true
|
10
10
|
|
11
11
|
>> p Rails.env
|
@@ -71,5 +71,5 @@ Cleanup
|
|
71
71
|
|
72
72
|
>> nuke_model_class(Product)
|
73
73
|
>> ActiveRecord::Base.connection.execute "drop table `products`;"
|
74
|
-
>> system "cd #{
|
74
|
+
>> system "cd #{TEST_APP_ROOT} && rake db:drop RAILS_ENV=mysql_test"
|
75
75
|
{.hidden}
|
data/test/prepare_testapp.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
system %(rake test:prepare_testapp)
|
3
|
-
|
4
|
-
|
5
|
-
require "#{TESTAPP_PATH}/config/environment"
|
3
|
+
FileUtils.chdir '/tmp/hobo_fields_testapp'
|
4
|
+
require 'config/environment'
|
6
5
|
require 'rails/generators'
|
7
6
|
Rails::Generators.configure!
|
8
7
|
|
data/test/rich_types.rdoctest
CHANGED
@@ -7,13 +7,6 @@ Our test requires to prepare the testapp:
|
|
7
7
|
|
8
8
|
doctest_require: 'prepare_testapp'
|
9
9
|
|
10
|
-
>>
|
11
|
-
ActiveRecord::Migration.create_table :articles do |t|
|
12
|
-
t.text :body
|
13
|
-
t.string :status
|
14
|
-
end
|
15
|
-
>>
|
16
|
-
|
17
10
|
{.hidden}
|
18
11
|
|
19
12
|
## `to_html` method
|
@@ -33,33 +26,26 @@ This class defines the methods `to_html` to customize the way the type is render
|
|
33
26
|
# Loud text always renderd in caps.
|
34
27
|
# It's rude to shout too much so it's not allowed to be
|
35
28
|
# longer than 100 characters
|
36
|
-
|
37
|
-
class LoudText < String
|
29
|
+
class LoudText < String
|
38
30
|
|
39
|
-
|
31
|
+
COLUMN_TYPE = :string
|
40
32
|
|
41
|
-
|
33
|
+
HoboFields.register_type(:loud, self)
|
42
34
|
|
43
|
-
|
44
|
-
|
45
|
-
|
35
|
+
def validate
|
36
|
+
"is too long (you shouldn't shout that much)" if length > 100
|
37
|
+
end
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
39
|
+
def format
|
40
|
+
# make sure we have enough exclamation marks
|
41
|
+
self =~ /!!!$/ ? self + "!!!" : self
|
42
|
+
end
|
51
43
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
>>
|
44
|
+
def to_html(xmldoctype = true)
|
45
|
+
upcase
|
46
|
+
end
|
58
47
|
|
59
|
-
|
60
|
-
=> "FOO<BAA"
|
61
|
-
>> LoudText.new("foO<BAa").to_html.html_safe?
|
62
|
-
=> false
|
48
|
+
end
|
63
49
|
|
64
50
|
If you place this class in `app/rich_types/loud_text.rb`, Hobo will load it automatically.
|
65
51
|
|
@@ -95,41 +81,10 @@ Provides validation of correct email address format.
|
|
95
81
|
>> bad.validate
|
96
82
|
=> "is invalid"
|
97
83
|
|
98
|
-
>> nasty = HoboFields::Types::EmailAddress.new("foo<nasty><nasty>@baa.com")
|
99
|
-
>> nasty.to_html
|
100
|
-
=> "foo<nasty><nasty> at baa dot com"
|
101
|
-
>> nasty.to_html.html_safe?
|
102
|
-
=> true
|
103
|
-
|
104
84
|
### `HoboFields::Types::HtmlString`
|
105
85
|
|
106
86
|
`HtmlString` provides no special behavior. The main reason for using this type is that the `to_html` method does not do any html-escaping. Use this for columns that store raw HTML in the database.
|
107
87
|
|
108
|
-
# no safety treatments are done by `to_html`.
|
109
|
-
# even if `nasty.to_html` is actually unsafe, it is marked as html_safe.
|
110
|
-
>> nasty = HoboFields::Types::HtmlString.new("p1<p>p2</p>p3<nasty>p4</nasty>p5<script>p6<script>p7</script>p8")
|
111
|
-
>> nasty.to_html
|
112
|
-
=> "p1<p>p2</p>p3<nasty>p4</nasty>p5<script>p6<script>p7</script>p8"
|
113
|
-
>> nasty.to_html.html_safe?
|
114
|
-
=> true
|
115
|
-
|
116
|
-
>>
|
117
|
-
class Article < ActiveRecord::Base
|
118
|
-
fields do
|
119
|
-
body HoboFields::Types::HtmlString
|
120
|
-
end
|
121
|
-
end
|
122
|
-
>> article = Article.create!(:body => "</div>>>p1<p>p2</p>p3<nasty>p4</nasty>p5<script>p6<script>p7</script>p8")
|
123
|
-
# some unsafe html fragements are removed on save,
|
124
|
-
# but there's no guarantees that it is well-formed
|
125
|
-
>> article.body
|
126
|
-
=> "</div>>>p1<p>p2</p>p3p4p5<script>p6p8"
|
127
|
-
>> article.body == article.body.to_html
|
128
|
-
=> true
|
129
|
-
>> article.body.to_html.html_safe?
|
130
|
-
=> true
|
131
|
-
|
132
|
-
|
133
88
|
### `HoboFields::Types::MarkdownString`
|
134
89
|
|
135
90
|
`HoboFields::Types::MarkdownString` provides a `to_html` that renders markdown syntax into html. It requires the bluecloth gem.
|
@@ -142,17 +97,12 @@ Provides validation of correct email address format.
|
|
142
97
|
And text can be *emphasised*
|
143
98
|
)
|
144
99
|
>> markdown.to_html
|
145
|
-
|
146
|
-
|
147
|
-
|
100
|
+
>> markdown = HoboFields::Types::MarkdownString.new "# This is a heading\n\nAnd text can be *emphasised*\n"
|
101
|
+
=>""
|
102
|
+
<h1>This is a heading</h1>
|
148
103
|
|
149
|
-
|
150
|
-
|
151
|
-
>> markdown = HoboFields::Types::MarkdownString.new("</div>>>p1<script>p2")
|
152
|
-
>> markdown.to_html
|
153
|
-
=> "<p></div>>>p1</p>"
|
154
|
-
>> markdown.to_html.html_safe?
|
155
|
-
=> true
|
104
|
+
<p>And text can be <em>emphasised</em></p>
|
105
|
+
>>
|
156
106
|
|
157
107
|
### `HoboFields::Types::TextileString`
|
158
108
|
|
@@ -164,16 +114,7 @@ Provides validation of correct email address format.
|
|
164
114
|
)
|
165
115
|
>> textile.to_html
|
166
116
|
=> "<p>Text can be <em>emphasised</em></p>"
|
167
|
-
>>
|
168
|
-
=> true
|
169
|
-
|
170
|
-
# some unsafe html fragements are removed by `to_html`,
|
171
|
-
# but there's no guarantees that it is well-formed
|
172
|
-
>> textile = HoboFields::Types::TextileString.new("</div>>>p1<script>p2")
|
173
|
-
>> textile.to_html
|
174
|
-
=> "<p></div>>>p1</p>"
|
175
|
-
>> textile.to_html.html_safe?
|
176
|
-
=> true
|
117
|
+
>>
|
177
118
|
|
178
119
|
### `HoboFields::Types::Text`
|
179
120
|
|
@@ -183,68 +124,16 @@ Provides validation of correct email address format.
|
|
183
124
|
|
184
125
|
Cat & Mouse)
|
185
126
|
>> text.to_html
|
186
|
-
=>
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
>> text = HoboFields::Types::Text.new("</div>>>p1<script>p2")
|
192
|
-
>> text.to_html
|
193
|
-
=> "</div>>>p1<script>p2"
|
194
|
-
>> text.to_html.html_safe?
|
195
|
-
=> true
|
127
|
+
=>
|
128
|
+
"Tom & Jerry<br />
|
129
|
+
<br />
|
130
|
+
Cat & Mouse"
|
131
|
+
>>
|
196
132
|
|
197
133
|
### `HoboFields::Types::PasswordString`
|
198
134
|
|
199
135
|
`HoboFields::Types::PasswordString` provides a simple `to_html` to prevent accidental display of a password. It simply returns "`[password hidden]`". The type is also used to indicate the need for an `<input type='password'>`
|
200
136
|
|
201
|
-
>> HoboFields::Types::PasswordString.new("pass<word>").to_html
|
202
|
-
=> "[password hidden]"
|
203
|
-
>> HoboFields::Types::PasswordString.new("pass<word>").to_html.html_safe?
|
204
|
-
=> true
|
205
|
-
|
206
|
-
### `HoboFields::Serialized`
|
207
|
-
|
208
|
-
This type lets you store an arbitrary object as serialized text into
|
209
|
-
the database column. You can optionally pass the :class option to
|
210
|
-
restrict the column type.
|
211
|
-
|
212
|
-
>>
|
213
|
-
>>
|
214
|
-
def migrate(renames={})
|
215
|
-
up, down = Generators::Hobo::Migration::Migrator.run(renames)
|
216
|
-
ActiveRecord::Migration.class_eval(up)
|
217
|
-
ActiveRecord::Base.send(:descendants).each { |model| model.reset_column_information }
|
218
|
-
[up, down]
|
219
|
-
end
|
220
|
-
{.hidden}
|
221
|
-
|
222
|
-
>>
|
223
|
-
class Vault1 < ActiveRecord::Base
|
224
|
-
fields do
|
225
|
-
content :serialized
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
>> migrate
|
230
|
-
>> Vault1.create!(:content => {:key => "in Vault"})
|
231
|
-
>> Vault1.first.content
|
232
|
-
=> {:key => "in Vault"}
|
233
|
-
|
234
|
-
>>
|
235
|
-
class Vault2 < ActiveRecord::Base
|
236
|
-
fields do
|
237
|
-
content :serialized, :class => Hash
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
>> migrate
|
242
|
-
>> Vault2.create!(:content => {:key => "in Vault"})
|
243
|
-
>> Vault2.first.content
|
244
|
-
=> {:key => "in Vault"}
|
245
|
-
>> Vault2.create!(:content => 17) rescue ActiveRecord::SerializationTypeMismatch
|
246
|
-
>> Vault2.all.size
|
247
|
-
=> 1 # second record not created because of type mismatch
|
248
137
|
|
249
138
|
## Enum Strings
|
250
139
|
|
@@ -328,11 +217,6 @@ Sometimes it's nice to have a proper type name. Here's one way you might go abou
|
|
328
217
|
>> Article.attr_type :status
|
329
218
|
=> Article::Status
|
330
219
|
|
331
|
-
>> Article::Status::PUBLISHED.to_html
|
332
|
-
=> "published"
|
333
|
-
>> Article::Status::PUBLISHED.to_html.html_safe?
|
334
|
-
=> true
|
335
|
-
|
336
220
|
### Translating EnumString's
|
337
221
|
|
338
222
|
Named EnumString's may be translated. Here is an example fr.yml:
|
@@ -359,8 +243,6 @@ The translated value is available via `to_html`:
|
|
359
243
|
|
360
244
|
>> Article::Status::PUBLISHED.to_html
|
361
245
|
=> "publiés"
|
362
|
-
>> Article::Status::PUBLISHED.to_html.html_safe?
|
363
|
-
=> true
|
364
246
|
|
365
247
|
Translations only work with named EnumString's. The recommended way of naming the EnumString is to assign it to a constant, but if you do not wish to do this, you can supply the name in an option:
|
366
248
|
|
@@ -369,26 +251,3 @@ Translations only work with named EnumString's. The recommended way of naming t
|
|
369
251
|
|
370
252
|
`tableize` will be called on your name to provide the translation key.
|
371
253
|
|
372
|
-
|
373
|
-
###
|
374
|
-
|
375
|
-
### `HoboFields::Types::RawHtmlString`
|
376
|
-
|
377
|
-
# no safety treatments are done by `to_html`.
|
378
|
-
# even if `nasty.to_html` is actually unsafe, it is marked as html_safe.
|
379
|
-
>> nasty = HoboFields::Types::RawHtmlString.new("p1<p>p2</p>p3<nasty>p4</nasty>p5<script>p6<script>p7</script>p8")
|
380
|
-
>> nasty.to_html
|
381
|
-
=> "p1<p>p2</p>p3<nasty>p4</nasty>p5<script>p6<script>p7</script>p8"
|
382
|
-
>> nasty.to_html.html_safe?
|
383
|
-
=> true
|
384
|
-
|
385
|
-
### `HoboFields::Types::RawMarkdownString`
|
386
|
-
|
387
|
-
# no safety treatments are done by `to_html`.
|
388
|
-
# even if `markdown.to_html` is actually unsafe, it is marked as html_safe.
|
389
|
-
>> markdown = HoboFields::Types::RawMarkdownString.new("</div>>>p1<script>p2")
|
390
|
-
>> markdown.to_html
|
391
|
-
=> "<p></div>>>p1<script>p2</p>"
|
392
|
-
>> markdown.to_html.html_safe?
|
393
|
-
=> true
|
394
|
-
|
metadata
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hobo_fields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
hash: -1637175975
|
5
|
+
prerelease: true
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
- pre10
|
11
|
+
version: 1.3.0.pre10
|
6
12
|
platform: ruby
|
7
13
|
authors:
|
8
14
|
- Tom Locke
|
@@ -10,53 +16,84 @@ autorequire:
|
|
10
16
|
bindir: bin
|
11
17
|
cert_chain: []
|
12
18
|
|
13
|
-
date:
|
19
|
+
date: 2010-10-10 00:00:00 -04:00
|
14
20
|
default_executable:
|
15
21
|
dependencies:
|
16
22
|
- !ruby/object:Gem::Dependency
|
17
|
-
name:
|
23
|
+
name: rails
|
18
24
|
prerelease: false
|
19
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
20
26
|
none: false
|
21
27
|
requirements:
|
22
|
-
- - "
|
28
|
+
- - ">="
|
23
29
|
- !ruby/object:Gem::Version
|
24
|
-
|
30
|
+
hash: 7
|
31
|
+
segments:
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
- 0
|
35
|
+
version: 3.0.0
|
25
36
|
type: :runtime
|
26
37
|
version_requirements: *id001
|
27
38
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
39
|
+
name: hobo_support
|
29
40
|
prerelease: false
|
30
41
|
requirement: &id002 !ruby/object:Gem::Requirement
|
31
42
|
none: false
|
32
43
|
requirements:
|
33
|
-
- - "
|
44
|
+
- - "="
|
34
45
|
- !ruby/object:Gem::Version
|
35
|
-
|
36
|
-
|
46
|
+
hash: -1637175975
|
47
|
+
segments:
|
48
|
+
- 1
|
49
|
+
- 3
|
50
|
+
- 0
|
51
|
+
- pre10
|
52
|
+
version: 1.3.0.pre10
|
53
|
+
type: :runtime
|
37
54
|
version_requirements: *id002
|
38
55
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
56
|
+
name: rubydoctest
|
40
57
|
prerelease: false
|
41
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
42
59
|
none: false
|
43
60
|
requirements:
|
44
61
|
- - ">="
|
45
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
46
66
|
version: "0"
|
47
67
|
type: :development
|
48
68
|
version_requirements: *id003
|
49
69
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
70
|
+
name: redcloth
|
51
71
|
prerelease: false
|
52
72
|
requirement: &id004 !ruby/object:Gem::Requirement
|
53
73
|
none: false
|
54
74
|
requirements:
|
55
75
|
- - ">="
|
56
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
57
80
|
version: "0"
|
58
81
|
type: :development
|
59
82
|
version_requirements: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bluecloth
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
type: :development
|
96
|
+
version_requirements: *id005
|
60
97
|
description: Rich field types and migration generator for Rails
|
61
98
|
email: tom@tomlocke.com
|
62
99
|
executables:
|
@@ -122,17 +159,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
159
|
requirements:
|
123
160
|
- - ">="
|
124
161
|
- !ruby/object:Gem::Version
|
162
|
+
hash: 3
|
163
|
+
segments:
|
164
|
+
- 0
|
125
165
|
version: "0"
|
126
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
167
|
none: false
|
128
168
|
requirements:
|
129
169
|
- - ">="
|
130
170
|
- !ruby/object:Gem::Version
|
171
|
+
hash: 23
|
172
|
+
segments:
|
173
|
+
- 1
|
174
|
+
- 3
|
175
|
+
- 6
|
131
176
|
version: 1.3.6
|
132
177
|
requirements: []
|
133
178
|
|
134
179
|
rubyforge_project: hobo
|
135
|
-
rubygems_version: 1.
|
180
|
+
rubygems_version: 1.3.7
|
136
181
|
signing_key:
|
137
182
|
specification_version: 3
|
138
183
|
summary: Rich field types and migration generator for Rails
|