ramaze 2011.07.25 → 2011.10.23

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 (181) hide show
  1. data/.gitignore +3 -0
  2. data/.mailmap +3 -2
  3. data/.travis.yml +17 -0
  4. data/.yardopts +13 -0
  5. data/README.md +95 -352
  6. data/examples/app/blog/app.rb +25 -64
  7. data/examples/app/blog/config.ru +11 -9
  8. data/examples/app/blog/controller/init.rb +29 -86
  9. data/examples/app/blog/controller/posts.rb +232 -0
  10. data/examples/app/blog/controller/users.rb +160 -0
  11. data/examples/app/blog/layout/default.xhtml +61 -0
  12. data/examples/app/blog/migrations/01_create_schema.rb +50 -0
  13. data/examples/app/blog/model/comment.rb +41 -54
  14. data/examples/app/blog/model/init.rb +41 -13
  15. data/examples/app/blog/model/post.rb +35 -0
  16. data/examples/app/blog/model/user.rb +105 -0
  17. data/examples/app/blog/public/.htaccess +24 -0
  18. data/examples/app/blog/public/css/grid.css +107 -0
  19. data/examples/app/blog/public/css/layout.css +203 -0
  20. data/examples/app/blog/public/css/reset.css +123 -0
  21. data/examples/app/blog/public/css/text.css +109 -0
  22. data/examples/app/blog/public/dispatch.fcgi +11 -0
  23. data/examples/app/blog/public/favicon.ico +0 -0
  24. data/examples/app/blog/public/images/bg.png +0 -0
  25. data/examples/app/blog/start.rb +18 -3
  26. data/examples/app/blog/view/feed.xhtml +23 -0
  27. data/examples/app/blog/view/form.xhtml +11 -0
  28. data/examples/app/blog/view/index.xhtml +44 -0
  29. data/examples/app/blog/view/users/form.xhtml +12 -0
  30. data/examples/app/blog/view/users/index.xhtml +30 -0
  31. data/examples/app/blog/view/users/login.xhtml +8 -0
  32. data/examples/app/blog/view/view.xhtml +68 -0
  33. data/{doc → guide}/AUTHORS +5 -3
  34. data/{doc → guide}/CHANGELOG +428 -0
  35. data/{doc/GPL → guide/GPL_LICENSE} +0 -0
  36. data/{doc/COPYING → guide/RUBY_LICENSE} +3 -6
  37. data/guide/_static/logo.png +0 -0
  38. data/guide/_static/logo.svg +49 -0
  39. data/guide/_static/ramaze_console.png +0 -0
  40. data/guide/css/common.css +20 -0
  41. data/guide/general/cache.md +167 -0
  42. data/guide/general/configuration.md +168 -0
  43. data/guide/general/contributing.md +108 -0
  44. data/guide/general/controllers.md +115 -0
  45. data/guide/general/helpers.md +76 -0
  46. data/guide/general/installation.md +58 -0
  47. data/guide/general/logging.md +99 -0
  48. data/guide/general/middlewares.md +100 -0
  49. data/guide/general/models.md +78 -0
  50. data/guide/general/principles.md +53 -0
  51. data/guide/general/ramaze_command.md +155 -0
  52. data/guide/general/routes.md +81 -0
  53. data/guide/general/sessions.md +140 -0
  54. data/guide/general/special_thanks.md +67 -0
  55. data/guide/general/testing.md +61 -0
  56. data/guide/general/views.md +322 -0
  57. data/guide/tutorials/introduction.md +259 -0
  58. data/lib/proto/config.ru +1 -1
  59. data/lib/proto/public/favicon.ico +0 -0
  60. data/lib/proto/view/index.xhtml +7 -7
  61. data/lib/ramaze.rb +4 -4
  62. data/lib/ramaze/app.rb +11 -11
  63. data/lib/ramaze/app_graph.rb +2 -4
  64. data/lib/ramaze/bin/console.rb +3 -3
  65. data/lib/ramaze/bin/create.rb +2 -2
  66. data/lib/ramaze/bin/restart.rb +4 -4
  67. data/lib/ramaze/bin/runner.rb +5 -5
  68. data/lib/ramaze/bin/start.rb +19 -4
  69. data/lib/ramaze/bin/status.rb +3 -3
  70. data/lib/ramaze/bin/stop.rb +3 -3
  71. data/lib/ramaze/cache.rb +1 -0
  72. data/lib/ramaze/cache/lru.rb +8 -4
  73. data/lib/ramaze/cache/memcache.rb +32 -13
  74. data/lib/ramaze/cache/redis.rb +164 -0
  75. data/lib/ramaze/cache/sequel.rb +43 -28
  76. data/lib/ramaze/controller.rb +1 -2
  77. data/lib/ramaze/dependencies.rb +40 -3
  78. data/lib/ramaze/helper/bench.rb +26 -16
  79. data/lib/ramaze/helper/blue_form.rb +46 -73
  80. data/lib/ramaze/helper/cache.rb +10 -6
  81. data/lib/ramaze/helper/csrf.rb +35 -39
  82. data/lib/ramaze/helper/disqus.rb +5 -4
  83. data/lib/ramaze/helper/email.rb +35 -24
  84. data/lib/ramaze/helper/erector.rb +9 -13
  85. data/lib/ramaze/helper/flash.rb +7 -9
  86. data/lib/ramaze/helper/formatting.rb +194 -179
  87. data/lib/ramaze/helper/gravatar.rb +4 -8
  88. data/lib/ramaze/helper/identity.rb +3 -3
  89. data/lib/ramaze/helper/layout.rb +23 -8
  90. data/lib/ramaze/helper/markaby.rb +1 -1
  91. data/lib/ramaze/helper/paginate.rb +46 -39
  92. data/lib/ramaze/helper/request_accessor.rb +3 -1
  93. data/lib/ramaze/helper/simple_captcha.rb +18 -17
  94. data/lib/ramaze/helper/stack.rb +1 -1
  95. data/lib/ramaze/helper/tagz.rb +4 -2
  96. data/lib/ramaze/helper/upload.rb +523 -0
  97. data/lib/ramaze/helper/user.rb +4 -8
  98. data/lib/ramaze/helper/xhtml.rb +11 -15
  99. data/lib/ramaze/log.rb +9 -6
  100. data/lib/ramaze/log/rotatinginformer.rb +62 -27
  101. data/lib/ramaze/log/syslog.rb +20 -15
  102. data/lib/ramaze/log/xosd.rb +2 -1
  103. data/lib/ramaze/reloader.rb +2 -0
  104. data/lib/ramaze/request.rb +11 -10
  105. data/lib/ramaze/setup.rb +23 -6
  106. data/lib/ramaze/snippets/array/put_within.rb +3 -9
  107. data/lib/ramaze/snippets/binding/locals.rb +5 -10
  108. data/lib/ramaze/snippets/fiber.rb +1 -23
  109. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +3 -6
  110. data/lib/ramaze/snippets/numeric/filesize_format.rb +3 -5
  111. data/lib/ramaze/snippets/numeric/time.rb +3 -7
  112. data/lib/ramaze/snippets/object/__dir__.rb +3 -7
  113. data/lib/ramaze/snippets/object/instance_variable_defined.rb +3 -6
  114. data/lib/ramaze/snippets/object/pretty.rb +3 -7
  115. data/lib/ramaze/snippets/object/scope.rb +7 -9
  116. data/lib/ramaze/snippets/proc/locals.rb +12 -12
  117. data/lib/ramaze/snippets/ramaze/acquire.rb +15 -14
  118. data/lib/ramaze/snippets/ramaze/deprecated.rb +1 -1
  119. data/lib/ramaze/snippets/ramaze/fiber.rb +1 -1
  120. data/lib/ramaze/snippets/ramaze/lru_hash.rb +2 -3
  121. data/lib/ramaze/snippets/ramaze/struct.rb +2 -4
  122. data/lib/ramaze/snippets/string/camel_case.rb +8 -10
  123. data/lib/ramaze/snippets/string/color.rb +3 -4
  124. data/lib/ramaze/snippets/string/end_with.rb +3 -6
  125. data/lib/ramaze/snippets/string/esc.rb +3 -8
  126. data/lib/ramaze/snippets/string/ord.rb +3 -8
  127. data/lib/ramaze/snippets/string/snake_case.rb +6 -9
  128. data/lib/ramaze/snippets/string/start_with.rb +3 -8
  129. data/lib/ramaze/snippets/string/unindent.rb +3 -6
  130. data/lib/ramaze/snippets/thread/into.rb +1 -3
  131. data/lib/ramaze/spec.rb +2 -31
  132. data/lib/ramaze/spec/bacon.rb +18 -2
  133. data/lib/ramaze/version.rb +1 -1
  134. data/lib/ramaze/view.rb +1 -1
  135. data/ramaze.gemspec +1 -1
  136. data/spec/helper.rb +2 -1
  137. data/spec/ramaze/bin/start.rb +16 -20
  138. data/spec/ramaze/cache/localmemcache.rb +4 -7
  139. data/spec/ramaze/cache/memcache.rb +3 -1
  140. data/spec/ramaze/cache/redis.rb +62 -0
  141. data/spec/ramaze/helper/blue_form.rb +33 -4
  142. data/spec/ramaze/helper/layout.rb +40 -7
  143. data/spec/ramaze/helper/upload.rb +149 -0
  144. data/spec/ramaze/helper/uploads/text_1.txt +1 -0
  145. data/spec/ramaze/helper/uploads/text_2.txt +1 -0
  146. data/spec/ramaze/log/growl.rb +4 -6
  147. data/spec/ramaze/log/syslog.rb +6 -0
  148. data/spec/ramaze/view/lokar.rb +5 -0
  149. data/spec/ramaze/view/nagoro.rb +5 -0
  150. data/tasks/authors.rake +1 -1
  151. data/tasks/bacon.rake +14 -5
  152. data/tasks/changelog.rake +1 -1
  153. data/tasks/yard.rake +12 -4
  154. metadata +277 -239
  155. data/doc/LEGAL +0 -26
  156. data/examples/app/blog/README +0 -3
  157. data/examples/app/blog/controller/comment.rb +0 -45
  158. data/examples/app/blog/controller/entry.rb +0 -85
  159. data/examples/app/blog/controller/main.rb +0 -20
  160. data/examples/app/blog/controller/tag.rb +0 -9
  161. data/examples/app/blog/layout/default.nag +0 -31
  162. data/examples/app/blog/model/entry.rb +0 -89
  163. data/examples/app/blog/model/tag.rb +0 -36
  164. data/examples/app/blog/public/css/screen.css +0 -273
  165. data/examples/app/blog/spec/blog.rb +0 -87
  166. data/examples/app/blog/view/comment/form.nag +0 -10
  167. data/examples/app/blog/view/comment/show.nag +0 -16
  168. data/examples/app/blog/view/entry/edit.nag +0 -14
  169. data/examples/app/blog/view/entry/feed.atom.nag +0 -8
  170. data/examples/app/blog/view/entry/feed.rss.nag +0 -7
  171. data/examples/app/blog/view/entry/index.nag +0 -7
  172. data/examples/app/blog/view/entry/new.nag +0 -13
  173. data/examples/app/blog/view/entry/show.nag +0 -36
  174. data/examples/app/blog/view/feed.atom.nag +0 -18
  175. data/examples/app/blog/view/feed.rss.nag +0 -25
  176. data/examples/app/blog/view/index.nag +0 -6
  177. data/examples/app/blog/view/tag/index.nag +0 -5
  178. data/lib/proto/public/ramaze.png +0 -0
  179. data/lib/ramaze/rest.rb +0 -36
  180. data/spec/ramaze/rest.rb +0 -28
  181. data/tasks/rcov.rake +0 -22
@@ -1,71 +1,32 @@
1
+ # This file contains your application, it requires dependencies and necessary
2
+ # parts of the application.
3
+ #
4
+ # It will be required from either `config.ru` or `start.rb`
5
+ #
6
+ # Note that the require 'rubygems' line is only required if you're running a
7
+ # Ruby implementation that's based on 1.8 such as REE or Rubinius (although I'm
8
+ # not sure if the latter actually requires this).
1
9
  require 'rubygems'
2
10
  require 'ramaze'
3
11
 
4
- Ramaze.setup :verbose => true do
5
- gem 'sequel', '3.9.0'
6
- gem 'maruku', '0.6.0'
7
- gem 'sqlite3-ruby', :lib => 'sqlite3'
8
- gem 'nagoro'
12
+ # This block of code automatically downloads and installs all the specified
13
+ # Gems. This is similar to how Bundler and Isolate work but in a much simpler
14
+ # way.
15
+ Ramaze.setup(:verbose => false) do
16
+ gem 'sequel'
17
+ gem 'sqlite3'
18
+ gem 'bcrypt-ruby', :lib => 'bcrypt'
19
+ gem 'rdiscount'
9
20
  end
10
21
 
11
- module Blog
12
- include Ramaze::Optioned
22
+ # Make sure that Ramaze knows where you are. Without this layouts and such
23
+ # wouldn't be rendered. While Ramaze.options.roots includes "." (the current
24
+ # directory) you should not rely on this path as it changes depending from what
25
+ # directory this script was called.
26
+ Ramaze.options.roots = [__DIR__]
13
27
 
14
- options.dsl do
15
- o 'Title of this blog', :title,
16
- 'Ramaze Blog'
28
+ # Initialize controllers and models
29
+ require __DIR__('model/init')
30
+ require __DIR__('controller/init')
17
31
 
18
- o 'Subtitle of the blog', :subtitle,
19
- 'manveru.thoughts.to_html'
20
-
21
- sub :author do
22
- o 'Your name', :name,
23
- 'Michael Fellinger'
24
-
25
- o 'Your email address', :email,
26
- 'm.fellinger@gmail.com'
27
-
28
- o 'URL pointing to you, uses the url of this blog if nil', :url,
29
- 'http://github.com/manveru'
30
- end
31
-
32
- sub :admin do
33
- o "Admin username", :name,
34
- 'manveru'
35
-
36
- o "Admin password", :password,
37
- 'letmein'
38
- end
39
-
40
- sub :sidebar do
41
- o "Elements to display in the sidebar", :elements,
42
- [:bio, :tagcloud, :history, :admin]
43
-
44
- sub :bio do
45
- o 'Describe yourself, you may use html', :text,
46
- "My name is Forrest, Forrest Gump.<br />
47
- I enjoy running, chocolate, talking, and Jenny."
48
- end
49
-
50
- sub :history do
51
- o "How many past entries should be shown in the history", :size,
52
- 20
53
- end
54
- end
55
-
56
- o 'Number of entries shown in entry listings', :list_size,
57
- 10
58
-
59
- o 'How many entries are shown in the feeds', :feed_size,
60
- 100
61
-
62
- o 'Feed UUID', :uuid,
63
- 'ramaze_blog'
64
-
65
- o "Time format used throughout the blog, see `ri Time.strftime`", :time_format,
66
- '%A, %d.%m.%Y at %R'
67
- end
68
- end
69
-
70
- require 'model/init'
71
- require 'controller/init'
32
+ Ramaze::Log.info('Logging in can be done by going to /users/login')
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env rackup
2
2
  #
3
3
  # config.ru for ramaze apps
4
- # use thin >= 1.0.0
5
- # thin start -R config.ru
6
4
  #
7
- # rackup is a useful tool for running Rack applications, which uses the
5
+ # Rackup is a useful tool for running Rack applications, which uses the
8
6
  # Rack::Builder DSL to configure middleware and build up applications easily.
9
7
  #
10
- # rackup automatically figures out the environment it is run in, and runs your
11
- # application as FastCGI, CGI, or standalone with Mongrel or WEBrickall from
8
+ # Rackup automatically figures out the environment it is run in, and runs your
9
+ # application as FastCGI, CGI, or standalone with Mongrel or WEBrick -- all from
12
10
  # the same configuration.
11
+ #
12
+ # Do not set the adapter.handler in here, it will be ignored.
13
+ # You can choose the adapter like `ramaze start -s mongrel` or set it in the
14
+ # 'start.rb' and use `ruby start.rb` instead.
15
+ require ::File.expand_path('../app', __FILE__)
16
+
17
+ Ramaze.start(:root => Ramaze.options.roots, :started => true)
13
18
 
14
- cwd = File.dirname(__FILE__)
15
- require "#{cwd}/start"
16
- Ramaze.start(:started => true)
17
- run Innate
19
+ run Ramaze
@@ -1,88 +1,31 @@
1
- module Blog
2
- class Controller < Ramaze::Controller
3
- engine :Nagoro
4
- layout(:default){|path, wish| wish !~ /rss|atom/ }
5
- map_layouts '/'
6
- map nil, :blog
7
- app.location = '/'
8
- trait :app => :blog
9
- helper :form, :auth, :formatting
10
-
11
- trait :auth_table => lambda{
12
- password = Digest::SHA1.hexdigest(Blog.options.admin.password)
13
- {Blog.options.admin.name => password}
14
- }
15
-
16
- private
17
-
18
- def author_url
19
- Blog.options.author.url || request.domain(Main.r('/'))
20
- end
21
-
22
- def sidebar
23
- out = Ramaze::Gestalt.new
24
-
25
- Blog.options.sidebar.elements.each do |element|
26
- name, title, *contents = __send__("sidebar_#{element}")
27
-
28
- out.ul(:class => name) do
29
- out.li(:class => :title){ title }
30
- contents.flatten.each do |content|
31
- out.li{ content.to_s }
32
- end
33
- end
34
- end
35
-
36
- out.to_s
37
- end
38
-
39
- def sidebar_bio
40
- return :bio, 'About me', Blog.options.sidebar.bio.text.to_s
41
- end
42
-
43
- def sidebar_admin
44
- if logged_in?
45
- links = [ a('New entry', Entries.r(:new)),
46
- a('Logout', Main.r(:logout)) ]
47
- return :actions, 'Administration', links
48
- else
49
- return :login, 'Login', <<FORM.strip
50
- <form method="post" action="#{r :login}">
51
- #{form_text 'Username', :username}
52
- #{form_password 'Password', :password}
53
- #{form_submit 'Login'}
54
- </form>
55
- FORM
56
- end
57
- end
58
-
59
- def sidebar_history
60
- limit = 4; Blog.options.sidebar.history.size
61
- entries = Entry.select(:id, :title).order(:published.desc).limit(limit)
62
-
63
- return :history, 'History',
64
- entries.map{|e| a(e.title, e.href) }
65
- end
66
-
67
- # Don't rel="tag" them, this is bad practice according to microformats
68
- #
69
- # The query makes sure that we only select tags that have entries
70
- # associated with them.
71
- def sidebar_tagcloud
72
- tags = Tag.filter(:id => EntriesTags.select(:tag_id)).select(:name).map(:name)
73
- cloud = []
74
-
75
- tagcloud(tags, 0.8, 2.0).each do |tag, weight|
76
- style = "font-size: %0.2fem" % weight
77
- cloud << "<a href='#{Tags.r(tag)}' style='#{style}'>#{h(tag)}</a>"
78
- end
79
-
80
- return :tagcloud, 'Tags', cloud.sort.join("\n")
81
- end
82
- end
1
+ ##
2
+ # Base controller that provides a few things used by sub controllers throughout
3
+ # this example application.
4
+ #
5
+ # @author Yorick Peterse
6
+ # @since 26-09-2011
7
+ #
8
+ class BaseController < Ramaze::Controller
9
+ engine :etanni
10
+ layout :default
11
+ helper :blue_form, :user, :xhtml, :paginate
12
+
13
+ # Configures the Paginate helper so that it shows a maximum of 10 posts per
14
+ # page and uses the "page" query string key to determine the current page.
15
+ # This will result in URLs such as /posts?page=2. Note that when calling the
16
+ # paginate() method you can override these settings.
17
+ trait :paginate => {
18
+ :var => 'page',
19
+ :limit => 10
20
+ }
21
+
22
+ # Tells the User helper what model class should be used for the authenticate()
23
+ # method. By default this is already set to "User" so technically this isn't
24
+ # required but to make it easier to understand what's going on I decided to
25
+ # put it here.
26
+ trait :user_model => User
83
27
  end
84
28
 
85
- require 'controller/main'
86
- require 'controller/entry'
87
- require 'controller/tag'
88
- require 'controller/comment'
29
+ # Load all other controllers
30
+ require __DIR__('posts')
31
+ require __DIR__('users')
@@ -0,0 +1,232 @@
1
+ ##
2
+ # The Posts controller is used to display a list of all the posts that have been
3
+ # added as well as providing a way of adding, removing and updating posts.
4
+ #
5
+ # @author Yorick Peterse
6
+ # @since 26-09-2011
7
+ #
8
+ class Posts < BaseController
9
+ map '/'
10
+
11
+ # Sets the content type and view name based on the extension in the URL. For
12
+ # example, a request to /posts/feed.rss would render the view feed.rss.xhtml
13
+ # and set the content type to application/rss+xml.
14
+ provide(:atom, :type => 'application/atom+xml') do |action, body|
15
+ # Disable the layout.
16
+ action.layout = false
17
+
18
+ # Let's make sure the body is actually rendered. Using "return" would cause
19
+ # a local jumper error.
20
+ body
21
+ end
22
+
23
+ # These methods require the user to be logged in. If this isn't the case the
24
+ # user will be redirected back to the previous page and a message is
25
+ # displayed.
26
+ before(:edit, :new, :save, :delete) do
27
+ # "unless logged_in?" is the same as "if !logged_in?" but in my opinion is a
28
+ # bit nicer to the eyes.
29
+ unless logged_in?
30
+ flash[:error] = 'You need to be logged in to view that page'
31
+
32
+ # Posts.r() is a method that generates a route to a given method and a set
33
+ # of parameters. Calling #to_s on this object would produce a string
34
+ # containing a URL. For example, Posts.r(:edit, 10).to_s would result in
35
+ # "/edit/10".
36
+ redirect(Posts.r(:index))
37
+ end
38
+ end
39
+
40
+ ##
41
+ # Shows an overview of all the posts that have been added. These posts are
42
+ # paginated using the Paginate helper.
43
+ #
44
+ # @author Yorick Peterse
45
+ # @since 26-09-2011
46
+ #
47
+ def index
48
+ @posts = paginate(Post.eager(:comments, :user))
49
+ @title = 'Posts'
50
+ end
51
+
52
+ ##
53
+ # Returns a list of all posts as either an RSS feed or an Atom feed.
54
+ #
55
+ # @author Yorick Peterse
56
+ # @since 27-09-2011
57
+ #
58
+ def feed
59
+ @posts = Post.all
60
+
61
+ render_view(:feed)
62
+ end
63
+
64
+ ##
65
+ # Shows a single post along with all it's comments.
66
+ #
67
+ # @author Yorick Peterse
68
+ # @since 26-09-2011
69
+ # @param [Fixnum] id The ID of the post to view.
70
+ #
71
+ def view(id)
72
+ @post = Post[id]
73
+
74
+ if @post.nil?
75
+ flash[:error] = 'The specified post is invalid'
76
+ redirect_referrer
77
+ end
78
+
79
+ @title = @post.title
80
+ @created_at = @post.created_at.strftime('%Y-%m-%d')
81
+ @new_comment = flash[:form_data] || Comment.new
82
+ end
83
+
84
+ ##
85
+ # Allows users to create a new post, given the user is logged in.
86
+ #
87
+ # @author Yorick Peterse
88
+ # @since 26-09-2011
89
+ #
90
+ def new
91
+ @post = flash[:form_data] || Post.new
92
+ @title = 'New post'
93
+
94
+ render_view(:form)
95
+ end
96
+
97
+ ##
98
+ # Allows a user to edit an existing blog post.
99
+ #
100
+ # @author Yorick Peterse
101
+ # @since 26-09-2011
102
+ # @param [Fixnum] id The ID of the blog post to edit.
103
+ #
104
+ def edit(id)
105
+ @post = flash[:form_data] || Post[id]
106
+
107
+ # Make sure the post is valid
108
+ if @post.nil?
109
+ flash[:error] = 'The specified post is invalid'
110
+ redirect_referrer
111
+ end
112
+
113
+ @title = "Edit #{@post.title}"
114
+
115
+ render_view(:form)
116
+ end
117
+
118
+ ##
119
+ # Adds a new comment to an existing post and redirects the user back to the
120
+ # post.
121
+ #
122
+ # @author Yorick Peterse
123
+ # @since 27-09-2011
124
+ #
125
+ def add_comment
126
+ data = request.subset(:post_id, :username, :comment)
127
+ comment = Comment.new
128
+
129
+ # If the user is logged in the user_id field should be set instead of the
130
+ # username field.
131
+ if logged_in?
132
+ data.delete('username')
133
+ data['user_id'] = user.id
134
+ end
135
+
136
+ begin
137
+ comment.update(data)
138
+ flash[:success] = 'The comment has been added'
139
+ rescue => e
140
+ Ramaze::Log.error(e)
141
+
142
+ flash[:form_errors] = comment.errors
143
+ flash[:error] = 'The comment could not be added'
144
+ end
145
+
146
+ redirect_referrer
147
+ end
148
+
149
+ ##
150
+ # Saves the changes made by Posts#edit() and Posts#new(). While these two
151
+ # methods could have their own methods for saving the data the entire process
152
+ # is almost identical and thus this would be somewhat useless.
153
+ #
154
+ # @author Yorick Peterse
155
+ # @since 26-09-2011
156
+ #
157
+ def save
158
+ # Fetch the POST data to use for a new Post object or for updating an
159
+ # existing one.
160
+ data = request.subset(:title, :body)
161
+ id = request.params['id']
162
+ data['user_id'] = user.id
163
+
164
+ # If an ID is given it's assumed the user wants to edit an existing post,
165
+ # otherwise a new one will be created.
166
+ if !id.nil? and !id.empty?
167
+ post = Post[id]
168
+
169
+ # Let's make sure the post is valid
170
+ if post.nil?
171
+ flash[:error] = 'The specified post is invalid'
172
+ redirect_referrer
173
+ end
174
+
175
+ success = 'The post has been updated'
176
+ error = 'The post could not be updated'
177
+ # Create a new post
178
+ else
179
+ post = Post.new
180
+ success = 'The post has been created'
181
+ error = 'The post could not be created'
182
+ end
183
+
184
+ # Now that we have a Post object and the messages to display it's time to
185
+ # actually insert/update the data. This is wrapped in a begin/rescue block
186
+ # so that any errors can be handled nicely.
187
+ begin
188
+ # Post#update() can be used for both new objects and existing ones. In
189
+ # case the object doesn't exist in the database it will be automatically
190
+ # created.
191
+ post.update(data)
192
+
193
+ flash[:success] = success
194
+
195
+ # Redirect the user back to the correct page.
196
+ redirect(Posts.r(:edit, post.id))
197
+ rescue => e
198
+ Ramaze::Log.error(e)
199
+
200
+ # Store the submitted data and the errors. The errors are used by
201
+ # BlueForm, the form data is used so that the user doesn't have to
202
+ # re-enter all data every time something goes wrong.
203
+ flash[:form_data] = post
204
+ flash[:form_errors] = post.errors
205
+ flash[:error] = error
206
+
207
+ redirect_referrer
208
+ end
209
+ end
210
+
211
+ ##
212
+ # Removes a single post from the database.
213
+ #
214
+ # @author Yorick Peterse
215
+ # @since 26-09-2011
216
+ # @param [Fixnum] id The ID of the post to remove.
217
+ #
218
+ def delete(id)
219
+ # The call is wrapped in a begin/rescue block so any errors can be handled
220
+ # properly. Without this the user would bump into a nasty stack trace and
221
+ # probably would have no clue as to what's going on.
222
+ begin
223
+ Post.filter(:id => id).destroy
224
+ flash[:success] = 'The specified post has been removed'
225
+ rescue => e
226
+ Ramaze::Log.error(e.message)
227
+ flash[:error] = 'The specified post could not be removed'
228
+ end
229
+
230
+ redirect(Posts.r(:index))
231
+ end
232
+ end # Posts