nitro 0.12.0 → 0.13.0

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.
Files changed (193) hide show
  1. data/{ChangeLog → CHANGELOG} +137 -0
  2. data/INSTALL +1 -2
  3. data/README +1 -1
  4. data/Rakefile +10 -61
  5. data/benchmark/{nitro/bench.rb → bench.rb} +1 -1
  6. data/benchmark/{nitro/simple-webrick-n-200.txt → simple-webrick-n-200.txt} +0 -0
  7. data/benchmark/{nitro/static-webrick-n-200.txt → static-webrick-n-200.txt} +0 -0
  8. data/benchmark/{nitro/tiny-lhttpd-n-200-c-5.txt → tiny-lhttpd-n-200-c-5.txt} +0 -0
  9. data/benchmark/{nitro/tiny-webrick-n-200-c-5.txt → tiny-webrick-n-200-c-5.txt} +0 -0
  10. data/benchmark/{nitro/tiny-webrick-n-200.txt → tiny-webrick-n-200.txt} +0 -0
  11. data/benchmark/{nitro/tiny2-webrick-n-200.txt → tiny2-webrick-n-200.txt} +0 -0
  12. data/doc/{ChangeLog.1 → CHANGELOG.1} +0 -0
  13. data/{RELEASES → doc/RELEASES} +46 -0
  14. data/doc/faq.txt +7 -0
  15. data/examples/README.windows +1 -1
  16. data/examples/ajax/controller.rb +21 -0
  17. data/examples/ajax/public/index.xhtml +70 -0
  18. data/examples/ajax/public/js/ajax.js +64 -0
  19. data/examples/ajax/run.rb +16 -0
  20. data/examples/blog/README +6 -3
  21. data/examples/blog/conf/apache.conf +2 -2
  22. data/examples/blog/conf/lhttpd.conf +2 -2
  23. data/examples/blog/log/apache.error_log +777 -0
  24. data/examples/blog/{root → public}/base.xsl +0 -0
  25. data/examples/blog/{root → public}/fcgi.rb +0 -0
  26. data/examples/blog/{root → public}/m/bubbles.gif +0 -0
  27. data/examples/blog/{root → public}/m/comments_curve.gif +0 -0
  28. data/examples/blog/{root → public}/m/down.gif +0 -0
  29. data/examples/blog/{root → public}/m/footer_bg.gif +0 -0
  30. data/examples/blog/{root → public}/m/garrow.gif +0 -0
  31. data/examples/blog/{root → public}/m/gbull.gif +0 -0
  32. data/examples/blog/{root → public}/m/grbull.gif +0 -0
  33. data/examples/blog/{root → public}/m/h1_bg.gif +0 -0
  34. data/examples/blog/{root → public}/m/header_bg.gif +0 -0
  35. data/examples/blog/{root → public}/m/nitro.gif +0 -0
  36. data/examples/blog/{root → public}/m/obull.gif +0 -0
  37. data/examples/blog/{root → public}/m/page_bg.gif +0 -0
  38. data/examples/blog/{root → public}/m/rss.gif +0 -0
  39. data/examples/blog/{root → public}/m/side_title_bg.gif +0 -0
  40. data/examples/blog/{root → public}/m/sidebar_bg.gif +0 -0
  41. data/examples/{no_xsl_blog/root → blog/public}/style.css +6 -0
  42. data/examples/blog/run.rb +10 -12
  43. data/examples/blog/{lib → src}/blog.rb +3 -3
  44. data/examples/blog/{lib/blog → src}/controller.rb +13 -2
  45. data/examples/blog/src/mailer.rb +23 -0
  46. data/examples/blog/{lib/blog/model.rb → src/models/blog.rb} +4 -7
  47. data/examples/blog/src/models/content.rb +52 -0
  48. data/examples/blog/src/views/blog_entry_email.xhtml +16 -0
  49. data/examples/blog/{root → src/views}/comments.xhtml +0 -0
  50. data/examples/blog/{root → src/views}/entry_form.xhtml +0 -0
  51. data/examples/blog/{root → src/views}/error.xhtml +0 -0
  52. data/examples/blog/{root → src/views}/index.xhtml +0 -0
  53. data/examples/blog/{root → src/views}/login.xhtml +0 -0
  54. data/examples/blog/{root → src/views}/recent_posts.xhtml +0 -0
  55. data/examples/blog/{root → src/views}/view_entry.xhtml +8 -0
  56. data/examples/blog/{root → src/views}/view_entry.xml +0 -0
  57. data/examples/blog/src/xsl/base.xsl +153 -0
  58. data/examples/blog/{root → src/xsl}/style.xsl +2 -2
  59. data/examples/no_xsl_blog/README +5 -1
  60. data/examples/no_xsl_blog/conf/apache.conf +2 -2
  61. data/examples/no_xsl_blog/conf/lhttpd.conf +2 -2
  62. data/examples/no_xsl_blog/lib/blog/model.rb +1 -1
  63. data/{lib/parts → examples/no_xsl_blog/lib}/content.rb +1 -11
  64. data/examples/no_xsl_blog/log/apache.error_log +405 -0
  65. data/examples/no_xsl_blog/{root → public}/comments.xhtml +0 -0
  66. data/examples/no_xsl_blog/{root → public}/entry_form.xhtml +0 -0
  67. data/examples/no_xsl_blog/{root → public}/fcgi.rb +0 -0
  68. data/examples/no_xsl_blog/{root → public}/index.xhtml +0 -0
  69. data/examples/no_xsl_blog/{root → public}/login.xhtml +0 -0
  70. data/examples/no_xsl_blog/{root → public}/m/bubbles.gif +0 -0
  71. data/examples/no_xsl_blog/{root → public}/m/comments_curve.gif +0 -0
  72. data/examples/no_xsl_blog/{root → public}/m/down.gif +0 -0
  73. data/examples/no_xsl_blog/{root → public}/m/footer_bg.gif +0 -0
  74. data/examples/no_xsl_blog/{root → public}/m/garrow.gif +0 -0
  75. data/examples/no_xsl_blog/{root → public}/m/gbull.gif +0 -0
  76. data/examples/no_xsl_blog/{root → public}/m/grbull.gif +0 -0
  77. data/examples/no_xsl_blog/{root → public}/m/h1_bg.gif +0 -0
  78. data/examples/no_xsl_blog/{root → public}/m/header_bg.gif +0 -0
  79. data/examples/no_xsl_blog/{root → public}/m/nitro.gif +0 -0
  80. data/examples/no_xsl_blog/{root → public}/m/obull.gif +0 -0
  81. data/examples/no_xsl_blog/{root → public}/m/page_bg.gif +0 -0
  82. data/examples/no_xsl_blog/{root → public}/m/rss.gif +0 -0
  83. data/examples/no_xsl_blog/{root → public}/m/side_title_bg.gif +0 -0
  84. data/examples/no_xsl_blog/{root → public}/m/sidebar_bg.gif +0 -0
  85. data/examples/no_xsl_blog/{root → public}/recent_posts.xhtml +0 -0
  86. data/examples/{blog/root → no_xsl_blog/public}/style.css +0 -0
  87. data/examples/no_xsl_blog/{root → public}/view_entry.xhtml +0 -0
  88. data/examples/no_xsl_blog/{root → public}/view_entry.xml +0 -0
  89. data/examples/tiny/conf/apache.conf +2 -2
  90. data/examples/tiny/log/apache.error_log +100 -0
  91. data/examples/tiny/{root → public}/fcgi.rb +0 -0
  92. data/examples/tiny/{root → public}/include.xhtml +0 -0
  93. data/examples/tiny/{root → public}/index.xhtml +0 -0
  94. data/{bin/proto/root/m → examples/tiny/public}/nitro.png +0 -0
  95. data/examples/tiny/{root → public}/upload.xhtml +0 -0
  96. data/examples/tiny/run.rb +1 -2
  97. data/examples/why_wiki/wiki.yml +1 -0
  98. data/install.rb +5 -2
  99. data/lib/nitro.rb +2 -6
  100. data/lib/nitro/adapters/fastcgi.rb +2 -2
  101. data/lib/nitro/adapters/webrick.rb +4 -4
  102. data/lib/nitro/conf.rb +5 -2
  103. data/lib/nitro/controller.rb +2 -2
  104. data/lib/nitro/dispatcher.rb +19 -8
  105. data/lib/nitro/mail.rb +252 -8
  106. data/lib/nitro/render.rb +24 -21
  107. data/lib/nitro/runner.rb +1 -1
  108. data/lib/nitro/scaffold.rb +2 -5
  109. data/lib/nitro/simple.rb +2 -1
  110. data/lib/nitro/template.rb +42 -2
  111. data/test/nitro/tc_controller.rb +9 -4
  112. data/test/nitro/tc_dispatcher.rb +4 -6
  113. data/test/nitro/tc_mail.rb +95 -0
  114. data/test/{root → public}/blog/list.xhtml +0 -0
  115. data/test/public/dummy_mailer/registration.xhtml +5 -0
  116. data/vendor/README +0 -1
  117. metadata +136 -181
  118. data/benchmark/og/bench.rb +0 -75
  119. data/benchmark/og/sqlite-no-prepare.1.txt +0 -13
  120. data/benchmark/og/sqlite-no-prepare.2.txt +0 -13
  121. data/benchmark/og/sqlite-prepare.1.txt +0 -13
  122. data/benchmark/og/sqlite-prepare.2.txt +0 -13
  123. data/bin/proto/README +0 -34
  124. data/bin/proto/conf/apache.conf +0 -1
  125. data/bin/proto/conf/app.conf.rb +0 -14
  126. data/bin/proto/conf/lhttpd.conf +0 -236
  127. data/bin/proto/ctl +0 -4
  128. data/bin/proto/lib/README +0 -5
  129. data/bin/proto/log/README +0 -3
  130. data/bin/proto/root/fcgi.rb +0 -6
  131. data/bin/proto/root/index.xhtml +0 -69
  132. data/bin/proto/root/style.css +0 -152
  133. data/bin/proto/root/style.xsl +0 -99
  134. data/doc/og_config.txt +0 -35
  135. data/doc/og_tutorial.txt +0 -595
  136. data/examples/og/README +0 -11
  137. data/examples/og/mock_example.rb +0 -50
  138. data/examples/og/mysql_to_psql.rb +0 -96
  139. data/examples/og/run.rb +0 -286
  140. data/examples/tiny/root/nitro.png +0 -0
  141. data/lib/glue.rb +0 -55
  142. data/lib/glue/array.rb +0 -61
  143. data/lib/glue/attribute.rb +0 -83
  144. data/lib/glue/cache.rb +0 -138
  145. data/lib/glue/flexob.rb +0 -12
  146. data/lib/glue/hash.rb +0 -122
  147. data/lib/glue/inflector.rb +0 -91
  148. data/lib/glue/logger.rb +0 -147
  149. data/lib/glue/misc.rb +0 -14
  150. data/lib/glue/mixins.rb +0 -36
  151. data/lib/glue/number.rb +0 -24
  152. data/lib/glue/object.rb +0 -32
  153. data/lib/glue/pool.rb +0 -60
  154. data/lib/glue/property.rb +0 -408
  155. data/lib/glue/string.rb +0 -162
  156. data/lib/glue/time.rb +0 -85
  157. data/lib/glue/validation.rb +0 -394
  158. data/lib/og.rb +0 -185
  159. data/lib/og/adapter.rb +0 -513
  160. data/lib/og/adapters/filesys.rb +0 -121
  161. data/lib/og/adapters/mysql.rb +0 -347
  162. data/lib/og/adapters/oracle.rb +0 -375
  163. data/lib/og/adapters/psql.rb +0 -273
  164. data/lib/og/adapters/sqlite.rb +0 -262
  165. data/lib/og/backend.rb +0 -297
  166. data/lib/og/connection.rb +0 -304
  167. data/lib/og/database.rb +0 -282
  168. data/lib/og/enchant.rb +0 -125
  169. data/lib/og/meta.rb +0 -373
  170. data/lib/og/mock.rb +0 -165
  171. data/lib/og/observer.rb +0 -53
  172. data/lib/og/typemacros.rb +0 -23
  173. data/lib/parts/README +0 -9
  174. data/test/glue/tc_attribute.rb +0 -22
  175. data/test/glue/tc_cache.rb +0 -45
  176. data/test/glue/tc_hash.rb +0 -38
  177. data/test/glue/tc_logger.rb +0 -39
  178. data/test/glue/tc_numbers.rb +0 -20
  179. data/test/glue/tc_property.rb +0 -89
  180. data/test/glue/tc_property_mixins.rb +0 -93
  181. data/test/glue/tc_property_type_checking.rb +0 -35
  182. data/test/glue/tc_strings.rb +0 -103
  183. data/test/glue/tc_validation.rb +0 -188
  184. data/test/og/tc_filesys.rb +0 -83
  185. data/test/og/tc_lifecycle.rb +0 -104
  186. data/test/og/tc_many_to_many.rb +0 -62
  187. data/test/og/tc_meta.rb +0 -55
  188. data/test/og/tc_observer.rb +0 -85
  189. data/test/og/tc_sqlite.rb +0 -87
  190. data/test/tc_og.rb +0 -355
  191. data/vendor/composite_sexp_processor.rb +0 -43
  192. data/vendor/parse_tree.rb +0 -745
  193. data/vendor/sexp_processor.rb +0 -453
data/examples/og/README DELETED
@@ -1,11 +0,0 @@
1
- = Og Example
2
-
3
- == run.rb
4
-
5
- A simple example that demonstrates some Og features. The example
6
- automatically creates a 'test' database.
7
-
8
- == mock_example.rb
9
-
10
- Demonstrates how easily the Og infrastructure can be mocked,
11
- for easy test unit writing.
@@ -1,50 +0,0 @@
1
- # = Og Mocking Example
2
- #
3
- # A simple example to demonstrate how to mock Og.
4
- # Very useful in test units.
5
- #
6
- # * George Moschovitis <gm@navel.gr>
7
- # (c) 2004-2005 Navel, all rights reserved.
8
- # $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
9
-
10
- require 'rubygems'
11
- require 'flexmock'
12
- require 'og'
13
- require 'og/mock'
14
-
15
- class Article
16
- prop_accessor :body, String
17
-
18
- def initialize(body = nil)
19
- @body = body
20
- end
21
- end
22
-
23
- class SimpleTest < Test::Unit::TestCase
24
-
25
- def setup
26
- @og = Og::MockDatabase.new
27
- end
28
-
29
- def teardown
30
- @og = nil
31
- end
32
-
33
- def test_me
34
- mocks = [
35
- Article.new('body1'),
36
- Article.new('body2'),
37
- Article.new('body3')
38
- ]
39
- @og.mock_handle(:load_all) { |klass, extrasql| mocks }
40
-
41
- # differnt ways to call the mocked method...
42
- puts 'Here are the articles:', Article.all
43
- puts 'Here are the articles:', Article.load_all
44
- puts 'Here are the articles:', @og.load_all(Article)
45
-
46
- # 3 times called
47
- assert_equal(3, @og.mock_count(:load_all))
48
- end
49
-
50
- end
@@ -1,96 +0,0 @@
1
- # = Og Mysql to PostgreSQL copy example
2
- #
3
- # A simple example to demonstrate the flexibility of
4
- # Og. Two connections to different databases are
5
- # created and data is copied from a MySQL database
6
- # to a PostgreSQL database.
7
- #
8
- # Og makes it easier to switch to a REAL database :)
9
- #
10
- # * George Moschovitis <gm@navel.gr>
11
- # (c) 2004-2005 Navel, all rights reserved.
12
- # $Id$
13
-
14
- raise 'WARNING, this example does not work yet, for the moment ' +
15
- 'just have a look at the source code.'
16
-
17
- require 'og'
18
-
19
- # An example managed object.
20
- # Looks like an ordinary Ruby object.
21
-
22
- class Article
23
- prop_accessor :name, :body, String
24
-
25
- def initialize(name = nil, body = nil)
26
- @name, @body = name, body
27
- end
28
- end
29
-
30
- # Configure databases.
31
-
32
- psql_config = {
33
- :address => 'localhost',
34
- :database => 'test',
35
- :backend => 'psql',
36
- :user => 'postgres',
37
- :password => 'navelrulez',
38
- :connection_count => 1
39
- }
40
-
41
- mysql_config = {
42
- :address => 'localhost',
43
- :database => 'mysql',
44
- :backend => 'psql',
45
- :user => 'postgres',
46
- :password => 'navelrulez',
47
- :connection_count => 1
48
- }
49
- =begin
50
- mysql_config = {
51
- :address => 'localhost',
52
- :database => 'test',
53
- :backend => 'mysql',
54
- :user => 'root',
55
- :password => 'navelrulez',
56
- :connection_count => 1
57
- }
58
- =end
59
-
60
- # Cleanup the databases, remove data from
61
- # earlier executions.
62
-
63
- Og::Database.drop!(psql_config)
64
- Og::Database.drop!(mysql_config)
65
-
66
- # Initialize Og.
67
-
68
- psql = Og::Database.new(psql_config)
69
- mysql = Og::Database.new(mysql_config)
70
-
71
- # First populate the mysql database.
72
-
73
- Og.use(mysql)
74
-
75
- a1 = Article.create('name1', 'body1')
76
- a1 = Article.create('name1', 'body1')
77
- a1 = Article.create('name1', 'body1')
78
-
79
- # Read all articles from Mysql.
80
-
81
- articles = Article.all
82
-
83
- # Switch to PostgreSQL.
84
-
85
- Og.use(psql)
86
-
87
- # Store all articles.
88
-
89
- for article in articles
90
- article.save!
91
- end
92
-
93
- # Fetch an article from PostgreSQL
94
- # as an example. Lookup by name.
95
-
96
- article = Article['name1']
data/examples/og/run.rb DELETED
@@ -1,286 +0,0 @@
1
- # A simple example to demonstrate the Og library.
2
- #
3
- # * George Moschovitis <gm@navel.gr>
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: run.rb 263 2005-02-23 13:45:08Z gmosx $
6
-
7
- require 'og'
8
-
9
- # Full debug information.
10
-
11
- $DBG = true
12
-
13
- # A child class.
14
-
15
- class Comment
16
- prop_accessor :body, String
17
-
18
- def initialize(body = nil)
19
- @body = body
20
- end
21
-
22
- def to_s
23
- return @body
24
- end
25
- end
26
-
27
- # forward declaration
28
- class ArticleComment < Comment; end
29
-
30
- # forward declaration
31
- class UserComment < Comment; end
32
-
33
- # forward declaration
34
- class Part; end
35
-
36
- # = A Parent class
37
- #
38
- class User
39
- prop_accessor :name, String
40
-
41
- has_many :comments, UserComment
42
-
43
- def initialize(name = nil)
44
- @name = name
45
- end
46
-
47
- def to_s
48
- return @name
49
- end
50
- end
51
-
52
-
53
- # A parent class.
54
-
55
- class Article
56
- prop_accessor :title, String
57
- prop_accessor :body, String
58
- # override the default O->R mapping
59
- prop_accessor :level, Fixnum, :sql => "smallint DEFAULT 1"
60
- # store a Ruby Hash in the Database. YAML
61
- # is used for serializing the attribute.
62
- # no need to define the class, but you can if you want.
63
- prop_accessor :options
64
- # exactly like the standard Ruby attr creates only the reader.
65
- prop :create_time, Time
66
-
67
- # define comment relation:
68
- has_many :comments, ArticleComment
69
-
70
- has_many :parts, Part
71
-
72
- # define author relation:
73
- belongs_to :author, User
74
-
75
- # this attribute is NOT stored in the db.
76
- attr_accessor :other_options
77
-
78
- # Managed object constructors with no args, take *args
79
- # as parameter to allow for Mixin chaining.
80
- #
81
- def initialize(title = nil, body = nil)
82
- @title, @body = title, body
83
- @create_time = Time.now
84
- @options = {}
85
- @other_options = {}
86
- end
87
-
88
- def to_s
89
- return "#@title: #@body"
90
- end
91
- end
92
-
93
- # A parent class.
94
-
95
- class Category
96
- prop_accessor :title, String
97
- prop_accessor :body, String
98
-
99
- # define a 'many to many' relation.
100
- many_to_many :articles, Article
101
-
102
- def initialize(title = nil)
103
- @title = title
104
- end
105
- end
106
-
107
-
108
- # Article comment.
109
-
110
- class ArticleComment < Comment
111
- belongs_to :article, Article
112
- end
113
-
114
- # User comment.
115
-
116
- class UserComment < Comment
117
- belongs_to :author, User
118
- end
119
-
120
- # Another child class.
121
-
122
- class Part
123
- prop_accessor :name, String
124
- belongs_to :article, Article
125
-
126
- def initialize(name = nil)
127
- @name = name
128
- end
129
-
130
- def to_s
131
- return @name
132
- end
133
- end
134
-
135
- # Og configuration.
136
- config = {
137
- :database => "test",
138
- :adapter => "sqlite",
139
- :connection_count => 2
140
- }
141
- =begin
142
- config = {
143
- # :address => "localhost",
144
- :database => "test",
145
- :adapter => "psql",
146
- :user => "postgres",
147
- :password => "navelrulez",
148
- :connection_count => 1
149
- }
150
-
151
- config = {
152
- :address => "localhost",
153
- :database => "test",
154
- :backend => "mysql",
155
- :user => "root",
156
- :password => "navelrulez",
157
- :connection_count => 1
158
- }
159
- =end
160
- # Cleanup the database for earlier executions
161
-
162
- Og::Database.drop!(config)
163
-
164
- # Initialize Og
165
-
166
- db = Og::Database.new(config)
167
-
168
- # Create some articles
169
-
170
- a1 = Article.new("Title1", "Body1")
171
- a1.save!
172
-
173
- # shortcut
174
- a2 = Article.create("Title2", "Body2")
175
-
176
- puts "\n\n"
177
- puts "* Get and print all articles:"
178
- articles = Article.all()
179
- articles.each { |a| puts a }
180
-
181
- # Create some comments
182
-
183
- c1 = ArticleComment.new("Comment 1")
184
- c1.article = a1
185
- c1.save!
186
-
187
- c2 = ArticleComment.new("Comment 2")
188
- # alternative way to set the parent.
189
- c2.article_oid = a1.oid
190
- # an alternative way to save
191
- db << c2
192
-
193
- # an alternative (easier and cooler) way to add children in a
194
- # has_many relation:
195
- c3 = ArticleComment.new("Comment 3")
196
- # add_comment is automatically added by Og.
197
- a1.add_comment(c3)
198
-
199
- puts "\n\n"
200
- puts "* Print all all comments for article 1:"
201
- a1.comments.each { |c| puts c }
202
-
203
- # Most Og commands allow you to fine-tune the low level
204
- # SQL code by passing extra_sql parameters, here is an
205
- # example
206
- puts "\n\n"
207
- puts "* comments with sql finetunings:"
208
- # use a standard SQL limit clause
209
- a1.comments("LIMIT 2").each { |c| puts c }
210
-
211
-
212
- # Change a managed object
213
- a1.title = "Changed Title"
214
- # Og knows that this is a managed object and executes
215
- # an SQL UPDATE instead of an SQL INSERT
216
- a1.save!
217
-
218
- puts "\n\n"
219
- Article.all.each { |a| puts a }
220
-
221
- # The previous command updates the whole object. It is used
222
- # when there are many updates or you dont care about speed.
223
- # To update only specific fields use pupdate or properties_update
224
- a2.pupdate! "title='A specific title'"
225
-
226
- puts "\n\n"
227
- Article.all.each { |a| puts a }
228
-
229
- # delete an object
230
- ArticleComment.delete(c3)
231
-
232
- puts "\n\n"
233
- ArticleComment.all.each { |a| puts a }
234
-
235
-
236
- # Serialize a hash
237
- a1.options = { "k1" => "val1", "k2" => "val2" }
238
- a1.save!
239
-
240
- # lookup an object
241
- article = Article[a1.oid]
242
-
243
- puts "\n\n"
244
- puts article.options.inspect
245
-
246
- u = User.new("gmosx")
247
- u.save!
248
-
249
- article = Article[1]
250
- # you can also lookup by the name property.
251
- article.author = User["gmosx"]
252
- article.save!
253
-
254
- part = Part.new("admin")
255
- part.article = article
256
- part.save!
257
-
258
- article.parts.each { |pa| puts pa }
259
-
260
- puts "\n\n"
261
- puts '---'
262
-
263
- c1 = Category.new("Category1").save!
264
- c2 = Category.new("Category2").save!
265
-
266
- article.add_category(c1)
267
- article.add_category(c2)
268
-
269
- puts '---'
270
-
271
- article.categories.each { |c| puts c.title }
272
-
273
- puts '---'
274
-
275
- c2.articles.each { |a| puts a.title }
276
-
277
- article.delete_category(c1)
278
-
279
- puts '---'
280
-
281
- article.categories.each { |c| puts c.title }
282
-
283
- # create and save the article in one step.
284
- article = Article.create("title", "body")
285
-
286
- puts '--', article.oid
Binary file