rails-erd 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -2
- data/CHANGES.rdoc +16 -2
- data/Gemfile +16 -0
- data/Gemfile.lock +54 -0
- data/README.rdoc +18 -192
- data/Rakefile +58 -1
- data/VERSION +1 -1
- data/lib/rails_erd.rb +12 -30
- data/lib/rails_erd/attribute.rb +19 -20
- data/lib/rails_erd/diagram.rb +36 -36
- data/lib/rails_erd/diagram/graphviz.rb +121 -22
- data/lib/rails_erd/diagram/templates/node.erb +6 -9
- data/lib/rails_erd/domain.rb +20 -9
- data/lib/rails_erd/entity.rb +23 -0
- data/lib/rails_erd/relationship.rb +97 -8
- data/lib/rails_erd/relationship/cardinality.rb +107 -25
- data/lib/rails_erd/tasks.rake +3 -2
- data/rails-erd.gemspec +7 -5
- data/test/test_helper.rb +34 -8
- data/test/unit/attribute_test.rb +26 -4
- data/test/unit/cardinality_test.rb +105 -13
- data/test/unit/diagram_test.rb +170 -0
- data/test/unit/domain_test.rb +8 -8
- data/test/unit/entity_test.rb +72 -1
- data/test/unit/graphviz_test.rb +188 -30
- data/test/unit/rake_task_test.rb +45 -2
- data/test/unit/relationship_test.rb +273 -172
- metadata +6 -5
data/.gitignore
CHANGED
data/CHANGES.rdoc
CHANGED
@@ -1,7 +1,21 @@
|
|
1
|
+
=== 0.3.0:
|
2
|
+
|
3
|
+
* Added the ability to support multiple styles of cardinality notations.
|
4
|
+
Currently supported types are 'simple' and 'advanced'.
|
5
|
+
* Added option to exclude indirect relationships (indirect=false).
|
6
|
+
* Added option to change or disable the diagram title (title='Custom title').
|
7
|
+
* Altered the type descriptions of attributes.
|
8
|
+
* Renamed options for flexibility and clarity.
|
9
|
+
* Improved internal logic to determine the cardinality of relationships.
|
10
|
+
* More versatile API that allows you to inspect relationships and their
|
11
|
+
cardinalities.
|
12
|
+
* Changed line widths to 1.0 to avoid invisible node boundaries with older
|
13
|
+
versions of Graphviz.
|
14
|
+
* Bundled examples based on actual applications.
|
15
|
+
|
1
16
|
=== 0.2.0
|
2
17
|
|
3
|
-
* Added simple way to create your own type of diagrams with a tiny amount of
|
4
|
-
code.
|
18
|
+
* Added simple way to create your own type of diagrams with a tiny amount of code.
|
5
19
|
* Improved internal API and documentation.
|
6
20
|
* Subtle changes in diagram style.
|
7
21
|
* Fixed error where non-mutual relationships might be inadvertently classified
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "rails-erd", :path => "."
|
4
|
+
gem "activesupport", :require => false
|
5
|
+
gem "activerecord", :require => "active_record"
|
6
|
+
gem "rake"
|
7
|
+
gem "jeweler"
|
8
|
+
|
9
|
+
platforms :ruby do
|
10
|
+
gem "sqlite3-ruby"
|
11
|
+
end
|
12
|
+
|
13
|
+
platforms :jruby do
|
14
|
+
gem "jdbc-sqlite3", :require => "jdbc/sqlite3"
|
15
|
+
gem "activerecord-jdbc-adapter", "1.0.0.beta2"
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rails-erd (0.2.0)
|
5
|
+
activerecord (~> 3.0.0)
|
6
|
+
activesupport (~> 3.0)
|
7
|
+
ruby-graphviz (~> 0.9.17)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.0.0)
|
13
|
+
activesupport (= 3.0.0)
|
14
|
+
builder (~> 2.1.2)
|
15
|
+
i18n (~> 0.4.1)
|
16
|
+
activerecord (3.0.0)
|
17
|
+
activemodel (= 3.0.0)
|
18
|
+
activesupport (= 3.0.0)
|
19
|
+
arel (~> 1.0.0)
|
20
|
+
tzinfo (~> 0.3.23)
|
21
|
+
activerecord-jdbc-adapter (1.0.0.beta2-java)
|
22
|
+
activesupport (3.0.0)
|
23
|
+
arel (1.0.1)
|
24
|
+
activesupport (~> 3.0.0)
|
25
|
+
builder (2.1.2)
|
26
|
+
gemcutter (0.6.1)
|
27
|
+
git (1.2.5)
|
28
|
+
i18n (0.4.1)
|
29
|
+
jdbc-sqlite3 (3.6.3.054)
|
30
|
+
jeweler (1.4.0)
|
31
|
+
gemcutter (>= 0.1.0)
|
32
|
+
git (>= 1.2.5)
|
33
|
+
rubyforge (>= 2.0.0)
|
34
|
+
json_pure (1.4.6)
|
35
|
+
rake (0.8.7)
|
36
|
+
ruby-graphviz (0.9.17)
|
37
|
+
rubyforge (2.0.4)
|
38
|
+
json_pure (>= 1.1.7)
|
39
|
+
sqlite3-ruby (1.3.1)
|
40
|
+
tzinfo (0.3.23)
|
41
|
+
|
42
|
+
PLATFORMS
|
43
|
+
java
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
activerecord
|
48
|
+
activerecord-jdbc-adapter (= 1.0.0.beta2)
|
49
|
+
activesupport
|
50
|
+
jdbc-sqlite3
|
51
|
+
jeweler
|
52
|
+
rails-erd!
|
53
|
+
rake
|
54
|
+
sqlite3-ruby
|
data/README.rdoc
CHANGED
@@ -1,213 +1,39 @@
|
|
1
1
|
= Rails ERD - Generate Entity-Relationship Diagrams for Rails applications
|
2
2
|
|
3
|
-
Rails ERD is a Rails plugin that allows
|
4
|
-
|
5
|
-
models are related. Having a diagram
|
6
|
-
documentation for your application.
|
3
|
+
{Rails ERD}[http://rails-erd.rubyforge.org/] is a Rails plugin that allows
|
4
|
+
you to easily generate a diagram based on your Active Record models. The
|
5
|
+
diagram gives an overview of how your models are related. Having a diagram
|
6
|
+
that describes your models is perfect documentation for your application.
|
7
7
|
|
8
8
|
The second goal of Rails ERD is to provide you with a tool to inspect your
|
9
9
|
application's domain model. If you don't like the default output, it is very
|
10
10
|
easy to use the API to build your own diagrams.
|
11
11
|
|
12
|
-
Rails ERD was created specifically for Rails 3. It uses
|
13
|
-
to figure out how your models are associated.
|
14
|
-
you may want to try Railroad[http://railroad.rubyforge.org/].
|
12
|
+
Rails ERD was created specifically for Rails 3. It uses Active Record's
|
13
|
+
built-in reflection capabilities to figure out how your models are associated.
|
15
14
|
|
16
|
-
==
|
15
|
+
== Preview
|
17
16
|
|
18
|
-
|
19
|
-
http://rails-erd.rubyforge.org/doc/
|
20
|
-
|
21
|
-
Source code at Github:
|
22
|
-
http://github.com/voormedia/rails-erd
|
23
|
-
|
24
|
-
Homepage:
|
25
|
-
http://rails-erd.rubyforge.org/
|
26
|
-
|
27
|
-
== Example output
|
28
|
-
|
29
|
-
This is an example diagram from an actual Rails application.
|
17
|
+
Here's an example entity-relationship diagram that was generated by Rails ERD:
|
30
18
|
|
31
19
|
http://rails-erd.rubyforge.org/examples/event-forms.png
|
32
20
|
|
33
|
-
|
34
|
-
|
35
|
-
Typo is a blogging application built in Rails. This is an excerpt from the
|
36
|
-
diagram that was generated from the Rails 3 branch (which is currently still
|
37
|
-
in development).
|
38
|
-
|
39
|
-
http://rails-erd.rubyforge.org/examples/typo-blog.png
|
40
|
-
|
41
|
-
{Download complete diagram as PDF}[http://rails-erd.rubyforge.org/examples/typo-blog.pdf]
|
42
|
-
|
43
|
-
== Getting started
|
44
|
-
|
45
|
-
In its most simple form, Rails ERD is a plugin for Rails 3 that provides you
|
46
|
-
with a Rake task to create an Entity-Relationship Diagram. It depends on the
|
47
|
-
Graphviz[http://www.graphviz.org/] visualisation library. In order to create
|
48
|
-
PDF files (the default), you should install or compile Graphviz with support
|
49
|
-
for Pango and Cairo.
|
50
|
-
|
51
|
-
For example, to install Graphviz with Homebrew:
|
21
|
+
== Learn more
|
52
22
|
|
53
|
-
|
54
|
-
|
55
|
-
Or with MacPorts:
|
56
|
-
|
57
|
-
% sudo port install graphviz
|
58
|
-
|
59
|
-
Next, install Rails ERD. Open your +Gemfile+, and add the following:
|
60
|
-
|
61
|
-
group :development do
|
62
|
-
gem 'rails-erd'
|
63
|
-
end
|
64
|
-
|
65
|
-
Tell Bundler to install Rails ERD:
|
66
|
-
|
67
|
-
% bundle install
|
68
|
-
|
69
|
-
You now have access to Rails ERD through Rake. Generate a new
|
70
|
-
Entity-Relationship Diagram for your Rails application:
|
71
|
-
|
72
|
-
% rake erd
|
73
|
-
|
74
|
-
All done! You will now have a file named <tt>ERD.pdf</tt> in your application root.
|
75
|
-
|
76
|
-
== Customisation
|
23
|
+
Homepage:
|
24
|
+
http://rails-erd.rubyforge.org/
|
77
25
|
|
78
|
-
|
79
|
-
|
26
|
+
Diagram gallery:
|
27
|
+
http://rails-erd.rubyforge.org/gallery.html
|
80
28
|
|
81
|
-
|
29
|
+
Installation instructions:
|
30
|
+
http://rails-erd.rubyforge.org/install.html
|
82
31
|
|
83
|
-
|
84
|
-
Defaults to +true+.
|
85
|
-
exclude_primary_keys:: Excludes primary key columns from attribute lists.
|
86
|
-
Defaults to +true+.
|
87
|
-
exclude_timestamps:: Excludes timestamp columns (<tt>created_at/on</tt> and
|
88
|
-
<tt>updated_at/on</tt>) from attribute lists. Defaults
|
89
|
-
to +true+.
|
90
|
-
exclude_unconnected:: Excludes entities that are not connected to other
|
91
|
-
entities from the diagram. Defaults to +true+.
|
92
|
-
file_type:: The file type of the generated diagram. Defaults to +pdf+, which
|
93
|
-
is the recommended format. Other formats may render significantly
|
94
|
-
worse than a PDF file. The available formats depend on your installation
|
95
|
-
of Graphviz.
|
96
|
-
orientation:: The direction of the hierarchy of entities. Either +horizontal+
|
97
|
-
or +vertical+. Defaults to +horizontal+. The orientation of the
|
98
|
-
PDF that is generated depends on the amount of hierarchy
|
99
|
-
in your models.
|
100
|
-
suppress_warnings:: When set to +true+, no warnings are printed to the
|
101
|
-
command line while processing the domain model. Defaults
|
102
|
-
to +false+.
|
103
|
-
|
104
|
-
== Custom diagrams
|
105
|
-
|
106
|
-
If you're completely unsatisfied with the diagrams that Rails ERD creates,
|
107
|
-
you can still use it to create your own diagrams. It provides you with an easy
|
108
|
-
way to create any kind of diagram based on your application's domain model.
|
109
|
-
|
110
|
-
As an example, a diagram class that generates code that can be used with
|
111
|
-
yUML (http://yuml.me) can be as simple as:
|
112
|
-
|
113
|
-
require "rails_erd/diagram"
|
114
|
-
|
115
|
-
class YumlDiagram < RailsERD::Diagram
|
116
|
-
def process_relationship(rel)
|
117
|
-
return if rel.indirect?
|
118
|
-
|
119
|
-
arrow = case
|
120
|
-
when rel.cardinality.one_to_one? then "1-1>"
|
121
|
-
when rel.cardinality.one_to_many? then "1-*>"
|
122
|
-
when rel.cardinality.many_to_many? then "*-*>"
|
123
|
-
end
|
124
|
-
|
125
|
-
instructions << "[#{rel.source}] #{arrow} [#{rel.destination}]"
|
126
|
-
end
|
127
|
-
|
128
|
-
def save
|
129
|
-
instructions * "\n"
|
130
|
-
end
|
131
|
-
|
132
|
-
def instructions
|
133
|
-
@instructions ||= []
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
Only 18 lines of code! Then, to generate the diagram (example based on the
|
138
|
-
domain model of Gemcutter):
|
139
|
-
|
140
|
-
YumlDiagram.create
|
141
|
-
#=> "[Rubygem] 1-*> [Ownership]
|
142
|
-
# [Rubygem] 1-*> [Subscription]
|
143
|
-
# [Rubygem] 1-*> [Version]
|
144
|
-
# [Rubygem] 1-1> [Linkset]
|
145
|
-
# [Rubygem] 1-*> [Dependency]
|
146
|
-
# [Version] 1-*> [Dependency]
|
147
|
-
# [User] 1-*> [Ownership]
|
148
|
-
# [User] 1-*> [Subscription]
|
149
|
-
# [User] 1-*> [WebHook]"
|
150
|
-
|
151
|
-
{See what that would look like}[http://yuml.me/diagram/scruffy/class/%5BRubygem%5D%201-*%3E%20%5BOwnership%5D,%20%5BRubygem%5D%201-*%3E%20%5BSubscription%5D,%20%5BRubygem%5D%201-*%3E%20%5BVersion%5D,%20%5BRubygem%5D%201-1%3E%20%5BLinkset%5D,%20%5BRubygem%5D%201-*%3E%20%5BDependency%5D,%20%5BVersion%5D%201-*%3E%20%5BDependency%5D,%20%5BUser%5D%201-*%3E%20%5BOwnership%5D,%20%5BUser%5D%201-*%3E%20%5BSubscription%5D,%20%5BUser%5D%201-*%3E%20%5BWebHook%5D].
|
152
|
-
|
153
|
-
== Internal API
|
154
|
-
|
155
|
-
Rails ERD also allows you to use its internal API to inspect your Rails domain
|
156
|
-
model. It is easy to generate alternative presentations of your Active Record
|
157
|
-
models this way. If used outside of Rails, install Rails ERD as a gem:
|
158
|
-
|
159
|
-
% gem install rails-erd
|
160
|
-
|
161
|
-
Suppose we have the following models:
|
162
|
-
|
163
|
-
class User < ActiveRecord::Base
|
164
|
-
has_many :posts
|
165
|
-
has_many :comments
|
166
|
-
end
|
167
|
-
|
168
|
-
class Post < ActiveRecord::Base
|
169
|
-
belongs_to :user
|
170
|
-
has_many :comments
|
171
|
-
end
|
172
|
-
|
173
|
-
class Comment < ActiveRecord::Base
|
174
|
-
belongs_to :user
|
175
|
-
belongs_to :post
|
176
|
-
end
|
177
|
-
|
178
|
-
Then you can inspect your domain model like this:
|
179
|
-
|
180
|
-
require "rails_erd/domain"
|
181
|
-
|
182
|
-
domain = RailsERD::Domain.generate
|
183
|
-
domain.entities
|
184
|
-
#=> [ #<RailsERD::Entity @model=Comment>,
|
185
|
-
# #<RailsERD::Entity @model=Post>,
|
186
|
-
# #<RailsERD::Entity @model=User> ]
|
187
|
-
|
188
|
-
domain.entities.first.connected?
|
189
|
-
#=> true
|
190
|
-
|
191
|
-
domain.relationships
|
192
|
-
#=> [ #<RailsERD::Relationship @source=Post @destination=Comment>,
|
193
|
-
# #<RailsERD::Relationship @source=User @destination=Comment>,
|
194
|
-
# #<RailsERD::Relationship @source=User @destination=Post> ]
|
195
|
-
|
196
|
-
domain.relationships.first.destination
|
197
|
-
#=> Comment
|
198
|
-
|
199
|
-
domain.relationships.first.mutual?
|
200
|
-
#=> true
|
201
|
-
|
202
|
-
domain.relationships.first.cardinality
|
203
|
-
#=> RailsERD::Relationship::Cardinality::OneToMany
|
204
|
-
|
205
|
-
The above is just a sample of what is possible. See the API documentation for
|
206
|
-
more details:
|
32
|
+
Internal API documentation:
|
207
33
|
http://rails-erd.rubyforge.org/doc/
|
208
34
|
|
209
|
-
|
210
|
-
|
35
|
+
Source code at Github:
|
36
|
+
http://github.com/voormedia/rails-erd
|
211
37
|
|
212
38
|
== About Rails ERD
|
213
39
|
|
data/Rakefile
CHANGED
@@ -13,9 +13,14 @@ Jeweler::Tasks.new do |spec|
|
|
13
13
|
spec.homepage = "http://rails-erd.rubyforge.org/"
|
14
14
|
|
15
15
|
spec.add_runtime_dependency "activerecord", "~> 3.0.0"
|
16
|
-
spec.add_runtime_dependency "activesupport", "~> 3.0
|
16
|
+
spec.add_runtime_dependency "activesupport", "~> 3.0"
|
17
17
|
spec.add_runtime_dependency "ruby-graphviz", "~> 0.9.17"
|
18
18
|
spec.add_development_dependency "sqlite3-ruby"
|
19
|
+
|
20
|
+
# Don't bundle examples or website in gem.
|
21
|
+
excluded = Dir["{examples,site}/**/*"]
|
22
|
+
spec.files -= excluded
|
23
|
+
spec.test_files -= excluded
|
19
24
|
end
|
20
25
|
|
21
26
|
Jeweler::GemcutterTasks.new
|
@@ -40,3 +45,55 @@ begin
|
|
40
45
|
end
|
41
46
|
rescue LoadError
|
42
47
|
end
|
48
|
+
|
49
|
+
desc "Generate diagrams for bundled examples"
|
50
|
+
task :examples do
|
51
|
+
require "rubygems"
|
52
|
+
require "bundler"
|
53
|
+
Bundler.require
|
54
|
+
require "rails_erd/diagram/graphviz"
|
55
|
+
|
56
|
+
Dir["examples/*/*"].each do |path|
|
57
|
+
name = File.basename(path)
|
58
|
+
print "==> Generating ERD for #{name.capitalize}... "
|
59
|
+
begin
|
60
|
+
# Load database schema.
|
61
|
+
ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
|
62
|
+
ActiveRecord::Migration.suppress_messages do
|
63
|
+
begin
|
64
|
+
require File.expand_path("#{path}/schema.rb", File.dirname(__FILE__))
|
65
|
+
rescue LoadError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Load domain models for this example.
|
70
|
+
Dir["#{path}/**/*.rb"].each do |model|
|
71
|
+
require File.expand_path(model, File.dirname(__FILE__))
|
72
|
+
end
|
73
|
+
|
74
|
+
# Skip empty domain models.
|
75
|
+
next if ActiveRecord::Base.descendants.empty?
|
76
|
+
|
77
|
+
puts "#{ActiveRecord::Base.descendants.length} models"
|
78
|
+
[:simple, :advanced].each do |notation|
|
79
|
+
filename = File.expand_path("examples/#{name}#{notation != :simple ? "-#{notation}" : ""}", File.dirname(__FILE__))
|
80
|
+
|
81
|
+
default_options = { :notation => notation, :filename => filename, :attributes => [:regular],
|
82
|
+
:title => name.classify + " domain model" }
|
83
|
+
|
84
|
+
specific_options = eval((File.read("#{path}/options.rb") rescue "")) || {}
|
85
|
+
|
86
|
+
# Generate ERD.
|
87
|
+
RailsERD::Diagram::Graphviz.create(default_options.merge(specific_options))
|
88
|
+
end
|
89
|
+
ensure
|
90
|
+
# Completely remove all loaded Active Record models.
|
91
|
+
ActiveRecord::Base.descendants.each do |model|
|
92
|
+
Object.send :remove_const, model.name.to_sym rescue nil
|
93
|
+
end
|
94
|
+
ActiveRecord::Base.direct_descendants.clear
|
95
|
+
Arel::Relation.send :class_variable_set, :@@connection_tables_primary_keys, {}
|
96
|
+
ActiveSupport::Dependencies::Reference.clear!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/rails_erd.rb
CHANGED
@@ -2,39 +2,19 @@ require "active_support/ordered_options"
|
|
2
2
|
require "rails_erd/railtie" if defined? Rails
|
3
3
|
|
4
4
|
# Rails ERD provides several options that allow you to customise the
|
5
|
-
# generation of the diagram and the domain model itself.
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# exclude_foreign_keys:: Excludes foreign key columns from attribute lists.
|
9
|
-
# Defaults to +true+.
|
10
|
-
# exclude_primary_keys:: Excludes primary key columns from attribute lists.
|
11
|
-
# Defaults to +true+.
|
12
|
-
# exclude_timestamps:: Excludes timestamp columns (<tt>created_at/on</tt> and
|
13
|
-
# <tt>updated_at/on</tt>) from attribute lists. Defaults
|
14
|
-
# to +true+.
|
15
|
-
# exclude_unconnected:: Excludes entities that are not connected to other
|
16
|
-
# entities from the diagram. Defaults to +true+.
|
17
|
-
# file_type:: The file type of the generated diagram. Defaults to +:pdf+, which
|
18
|
-
# is the recommended format. Other formats may render significantly
|
19
|
-
# worse than a PDF file.
|
20
|
-
# orientation:: The direction of the hierarchy of entities. Either +:horizontal+
|
21
|
-
# or +:vertical+. Defaults to +:horizontal+. The orientation of the
|
22
|
-
# PDF that is generated depends on the amount of hierarchy
|
23
|
-
# in your models.
|
24
|
-
# suppress_warnings:: When set to +true+, no warnings are printed to the
|
25
|
-
# command line while processing the domain model. Defaults
|
26
|
-
# to +false+.
|
5
|
+
# generation of the diagram and the domain model itself. For an overview of
|
6
|
+
# all options available in Rails ERD, see README.rdoc.
|
27
7
|
#
|
28
8
|
# You can specify the option on the command line if you use Rails ERD with
|
29
9
|
# Rake:
|
30
10
|
#
|
31
|
-
# % rake erd orientation=vertical
|
11
|
+
# % rake erd orientation=vertical title='My model diagram'
|
32
12
|
#
|
33
13
|
# When using Rails ERD from within Ruby, you can set the options on the
|
34
14
|
# RailsERD namespace module:
|
35
15
|
#
|
36
16
|
# RailsERD.options.orientation = :vertical
|
37
|
-
# RailsERD.options.
|
17
|
+
# RailsERD.options.title = "My model diagram"
|
38
18
|
module RailsERD
|
39
19
|
class << self
|
40
20
|
# Access to default options. Any instance of RailsERD::Domain and
|
@@ -43,12 +23,14 @@ module RailsERD
|
|
43
23
|
end
|
44
24
|
|
45
25
|
self.options = ActiveSupport::OrderedOptions[
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
26
|
+
:attributes, :regular,
|
27
|
+
:disconnected, true,
|
28
|
+
:filename, "ERD",
|
29
|
+
:filetype, :pdf,
|
30
|
+
:indirect, true,
|
31
|
+
:notation, :simple,
|
51
32
|
:orientation, :horizontal,
|
52
|
-
:
|
33
|
+
:warn, true,
|
34
|
+
:title, true
|
53
35
|
]
|
54
36
|
end
|