cornerstone 0.0.1 → 0.0.5

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 (177) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.lock +168 -0
  5. data/Guardfile +22 -0
  6. data/README.rdoc +4 -1
  7. data/Rakefile +11 -1
  8. data/TODO +11 -0
  9. data/VERSION +1 -0
  10. data/app/assets/images/.gitkeep +0 -0
  11. data/app/assets/javascripts/.gitkeep +0 -0
  12. data/app/assets/javascripts/cornerstone.js +11 -0
  13. data/app/assets/javascripts/cornerstone/discussions.js +2 -0
  14. data/app/assets/javascripts/cornerstone/help.js +2 -0
  15. data/app/assets/stylesheets/.gitkeep +0 -0
  16. data/app/assets/stylesheets/cornerstone.css +8 -0
  17. data/app/assets/stylesheets/cornerstone/discussions.css +4 -0
  18. data/app/assets/stylesheets/cornerstone/help.css +4 -0
  19. data/app/controllers/.gitkeep +0 -0
  20. data/app/controllers/cornerstone/admin/application_controller.rb +7 -0
  21. data/app/controllers/cornerstone/admin/articles_controller.rb +61 -0
  22. data/app/controllers/cornerstone/admin/categories_controller.rb +46 -0
  23. data/app/controllers/cornerstone/admin/discussions_controller.rb +32 -0
  24. data/app/controllers/cornerstone/application_controller.rb +6 -0
  25. data/app/controllers/cornerstone/discussions_controller.rb +58 -0
  26. data/app/controllers/cornerstone/help_controller.rb +11 -0
  27. data/app/controllers/cornerstone/posts_controller.rb +66 -0
  28. data/app/helpers/.gitkeep +0 -0
  29. data/app/helpers/cornerstone/application_helper.rb +5 -0
  30. data/app/helpers/cornerstone/discussions_helper.rb +16 -0
  31. data/app/helpers/cornerstone/help_helper.rb +4 -0
  32. data/app/mailers/cornerstone/cornerstone_mailer.rb +31 -0
  33. data/app/models/.gitkeep +0 -0
  34. data/app/models/cornerstone/article.rb +20 -0
  35. data/app/models/cornerstone/category.rb +45 -0
  36. data/app/models/cornerstone/discussion.rb +90 -0
  37. data/app/models/cornerstone/post.rb +103 -0
  38. data/app/models/cornerstone/post_observer.rb +23 -0
  39. data/app/views/.gitkeep +0 -0
  40. data/app/views/cornerstone/admin/articles/_article.html.erb +9 -0
  41. data/app/views/cornerstone/admin/articles/_form.html.erb +22 -0
  42. data/app/views/cornerstone/admin/articles/edit.html.erb +7 -0
  43. data/app/views/cornerstone/admin/articles/index.html.erb +25 -0
  44. data/app/views/cornerstone/admin/articles/new.html.erb +6 -0
  45. data/app/views/cornerstone/admin/articles/show.html.erb +4 -0
  46. data/app/views/cornerstone/admin/categories/_category.html.erb +12 -0
  47. data/app/views/cornerstone/admin/categories/_form.html.erb +17 -0
  48. data/app/views/cornerstone/admin/categories/edit.html.erb +6 -0
  49. data/app/views/cornerstone/admin/categories/index.html.erb +11 -0
  50. data/app/views/cornerstone/admin/categories/new.html.erb +6 -0
  51. data/app/views/cornerstone/admin/discussions/edit.html.erb +7 -0
  52. data/app/views/cornerstone/cornerstone_mailer/new_discussion.html.erb +14 -0
  53. data/app/views/cornerstone/cornerstone_mailer/new_discussion.text.erb +5 -0
  54. data/app/views/cornerstone/cornerstone_mailer/new_discussion_user.html.erb +7 -0
  55. data/app/views/cornerstone/cornerstone_mailer/new_post.html.erb +7 -0
  56. data/app/views/cornerstone/cornerstone_mailer/new_post.text.erb +8 -0
  57. data/app/views/cornerstone/discussions/_discussion.html.erb +12 -0
  58. data/app/views/cornerstone/discussions/_discussion_category.html.erb +14 -0
  59. data/app/views/cornerstone/discussions/_form.html.erb +33 -0
  60. data/app/views/cornerstone/discussions/_latest_discussion.html.erb +4 -0
  61. data/app/views/cornerstone/discussions/categorical_index.html.erb +27 -0
  62. data/app/views/cornerstone/discussions/index.html.erb +25 -0
  63. data/app/views/cornerstone/discussions/new.html.erb +6 -0
  64. data/app/views/cornerstone/discussions/show.html.erb +19 -0
  65. data/app/views/cornerstone/help/index.html.erb +7 -0
  66. data/app/views/cornerstone/posts/_fields.html.erb +44 -0
  67. data/app/views/cornerstone/posts/_form.html.erb +19 -0
  68. data/app/views/cornerstone/posts/_post.html.erb +17 -0
  69. data/app/views/cornerstone/posts/edit.html.erb +9 -0
  70. data/app/views/cornerstone/shared/_errors.html.erb +11 -0
  71. data/app/views/cornerstone/shared/_flash_messages.html.erb +15 -0
  72. data/app/views/layouts/cornerstone/application.html.erb +16 -0
  73. data/config/cucumber.yml +8 -0
  74. data/config/locales/cornerstone.action_mailer.en.yml +9 -0
  75. data/config/routes.rb +24 -0
  76. data/cornerstone-0.0.1.gem +0 -0
  77. data/cornerstone.gemspec +33 -0
  78. data/db/migrate/20110723004024_create_cornerstone_discussions.rb +17 -0
  79. data/db/migrate/20110804190853_create_cornerstone_categories.rb +15 -0
  80. data/db/migrate/20110809233551_create_cornerstone_posts.rb +13 -0
  81. data/db/migrate/20111006172857_create_cornerstone_articles.rb +12 -0
  82. data/lib/cornerstone.rb +6 -0
  83. data/lib/cornerstone/acts_as_cornerstone_user.rb +79 -0
  84. data/lib/cornerstone/config.rb +33 -0
  85. data/lib/cornerstone/controller_additions.rb +25 -0
  86. data/lib/cornerstone/engine.rb +8 -1
  87. data/lib/cornerstone/exceptions.rb +16 -0
  88. data/lib/cornerstone/helpers.rb +35 -0
  89. data/lib/tasks/cucumber.rake +65 -0
  90. data/lib/templates/cornerstone_config.rb +31 -0
  91. data/script/cucumber +10 -0
  92. data/script/rails +7 -0
  93. data/spec/controllers/cornerstone/admin/articles_controller_spec.rb +250 -0
  94. data/spec/controllers/cornerstone/admin/categories_controller_spec.rb +205 -0
  95. data/spec/controllers/cornerstone/admin/discussions_controller_spec.rb +95 -0
  96. data/spec/controllers/cornerstone/application_controller_spec.rb +34 -0
  97. data/spec/controllers/cornerstone/discussions_controller_spec.rb +157 -0
  98. data/spec/controllers/cornerstone/help_controller_spec.rb +20 -0
  99. data/spec/controllers/cornerstone/posts_controller_spec.rb +212 -0
  100. data/spec/dummy/Rakefile +7 -0
  101. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  102. data/spec/dummy/app/assets/javascripts/tester.js +2 -0
  103. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  104. data/spec/dummy/app/assets/stylesheets/tester.css +4 -0
  105. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  106. data/spec/dummy/app/controllers/tester_controller.rb +7 -0
  107. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  108. data/spec/dummy/app/helpers/tester_helper.rb +6 -0
  109. data/spec/dummy/app/mailers/.gitkeep +0 -0
  110. data/spec/dummy/app/models/.gitkeep +0 -0
  111. data/spec/dummy/app/models/user.rb +23 -0
  112. data/spec/dummy/app/views/devise/confirmations/new.html.erb +12 -0
  113. data/spec/dummy/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  114. data/spec/dummy/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  115. data/spec/dummy/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  116. data/spec/dummy/app/views/devise/passwords/edit.html.erb +16 -0
  117. data/spec/dummy/app/views/devise/passwords/new.html.erb +12 -0
  118. data/spec/dummy/app/views/devise/registrations/edit.html.erb +29 -0
  119. data/spec/dummy/app/views/devise/registrations/new.html.erb +22 -0
  120. data/spec/dummy/app/views/devise/sessions/new.html.erb +19 -0
  121. data/spec/dummy/app/views/devise/shared/_links.erb +25 -0
  122. data/spec/dummy/app/views/devise/unlocks/new.html.erb +12 -0
  123. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  124. data/spec/dummy/app/views/tester/index.html.erb +14 -0
  125. data/spec/dummy/config.ru +4 -0
  126. data/spec/dummy/config/application.rb +42 -0
  127. data/spec/dummy/config/boot.rb +10 -0
  128. data/spec/dummy/config/database.yml +28 -0
  129. data/spec/dummy/config/environment.rb +5 -0
  130. data/spec/dummy/config/environments/development.rb +31 -0
  131. data/spec/dummy/config/environments/production.rb +54 -0
  132. data/spec/dummy/config/environments/test.rb +39 -0
  133. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  134. data/spec/dummy/config/initializers/cornerstone_config.rb +30 -0
  135. data/spec/dummy/config/initializers/devise.rb +204 -0
  136. data/spec/dummy/config/initializers/inflections.rb +10 -0
  137. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  138. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  139. data/spec/dummy/config/initializers/session_store.rb +8 -0
  140. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  141. data/spec/dummy/config/locales/devise.en.yml +53 -0
  142. data/spec/dummy/config/locales/en.yml +5 -0
  143. data/spec/dummy/config/routes.rb +65 -0
  144. data/spec/dummy/db/migrate/20110724011421_create_user.rb +11 -0
  145. data/spec/dummy/db/migrate/20110724194307_devise_create_users.rb +41 -0
  146. data/spec/dummy/db/migrate/20110804174004_add_name_to_user.rb +5 -0
  147. data/spec/dummy/db/schema.rb +76 -0
  148. data/spec/dummy/log/.gitkeep +0 -0
  149. data/spec/dummy/public/404.html +26 -0
  150. data/spec/dummy/public/422.html +26 -0
  151. data/spec/dummy/public/500.html +26 -0
  152. data/spec/dummy/public/favicon.ico +0 -0
  153. data/spec/dummy/script/rails +6 -0
  154. data/spec/dummy/test/functional/tester_controller_test.rb +9 -0
  155. data/spec/dummy/test/unit/helpers/tester_helper_test.rb +4 -0
  156. data/spec/fixtures/cornerstone/cornerstone_mailer/new_discussion +3 -0
  157. data/spec/lib/cornerstone/acts_as_cornerstone_user_spec.rb +56 -0
  158. data/spec/lib/cornerstone/helpers_spec.rb +32 -0
  159. data/spec/mailers/cornerstone/cornerstone_mailer_spec.rb +55 -0
  160. data/spec/models/cornerstone/article_spec.rb +25 -0
  161. data/spec/models/cornerstone/category_spec.rb +97 -0
  162. data/spec/models/cornerstone/discussion_spec.rb +243 -0
  163. data/spec/models/cornerstone/post_observer_spec.rb +65 -0
  164. data/spec/models/cornerstone/post_spec.rb +210 -0
  165. data/spec/requests/emails_spec.rb +51 -0
  166. data/spec/requests/interact_discussions_spec.rb +103 -0
  167. data/spec/requests/manage_articles_spec.rb +59 -0
  168. data/spec/requests/manage_categories_spec.rb +64 -0
  169. data/spec/requests/view_home_spec.rb +26 -0
  170. data/spec/spec_helper.rb +40 -0
  171. data/spec/support/devise.rb +4 -0
  172. data/spec/support/factories.rb +62 -0
  173. data/spec/support/general_helper_methods.rb +20 -0
  174. data/spec/support/mailer_macros.rb +15 -0
  175. data/spec/support/mass_assignment.rb +46 -0
  176. data/tmp/log/development.log +0 -0
  177. metadata +301 -20
@@ -0,0 +1,6 @@
1
+ module Cornerstone
2
+ class ApplicationController < ActionController::Base
3
+
4
+ end
5
+ end
6
+
@@ -0,0 +1,58 @@
1
+ module Cornerstone
2
+ class DiscussionsController < ApplicationController
3
+
4
+ respond_to :html
5
+
6
+ # GET /cornerstone/discussions/
7
+ def index
8
+ @categories = Category.discussions
9
+ end
10
+
11
+ # GET /cornerstone/discussions/new
12
+ def new
13
+ @categories = Category.discussions
14
+ @category = Category.find(params[:cat]) if params[:cat]
15
+ @discussion = Discussion.new
16
+ @discussion.category_id = @category.id if @category
17
+ @discussion.posts.build
18
+ respond_with(@discussion)
19
+ end
20
+
21
+ # GET /cornerstone/discussions/:category
22
+ def category
23
+ @category = Category.includes(:discussions => :posts).find(params[:category])
24
+ @discussions = @category.discussions
25
+ respond_with(@discussions, :template => "cornerstone/discussions/categorical_index")
26
+ end
27
+
28
+ # GET /cornerstone/discussions/:category/:id
29
+ def show
30
+ @discussion = Discussion.includes(:posts => :user).find(params[:id])
31
+ @new_post = Post.new
32
+ @posts = @discussion.posts
33
+ end
34
+
35
+ # POST /cornerstone/discussions/
36
+ def create
37
+ @discussion = Discussion.new(params[:discussion])
38
+
39
+ # assign user if signed in
40
+ if current_cornerstone_user
41
+ @discussion.user = current_cornerstone_user
42
+ @discussion.posts.first.user = current_cornerstone_user
43
+ end
44
+
45
+ respond_with(@discussion.category, @discussion) do |format|
46
+ if @discussion.save
47
+ flash[:notice] = 'Discussion was successfully created.'
48
+ format.html {redirect_to category_discussion_path(@discussion.category, @discussion)}
49
+ else
50
+ @categories = Category.discussions
51
+ format.html {render :new}
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+
@@ -0,0 +1,11 @@
1
+ module Cornerstone
2
+ class HelpController < ApplicationController
3
+
4
+ # GET /
5
+ def index
6
+ @discussion_categories = Category.select("name, item_count").discussions
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,66 @@
1
+ module Cornerstone
2
+ class PostsController < ApplicationController
3
+ respond_to :html
4
+
5
+ # POST /cornerstone/discussions/:discussion_id/posts
6
+ def create
7
+ @discussion = Discussion.includes(:posts => :user).find(params[:discussion_id])
8
+ existing_posts = @discussion.posts.dup
9
+ @post = @discussion.posts.new(params[:post])
10
+
11
+ # assign user if signed in
12
+ if current_cornerstone_user
13
+ @post.user = current_cornerstone_user
14
+ end
15
+
16
+ respond_with(@discussion, @post) do |format|
17
+ if @post.save
18
+ # close discussion if commit param dictates
19
+ unless params[:comment_close].nil?
20
+ @discussion.update_attribute(:status, Discussion::STATUS.last)
21
+ else
22
+ # re-open discussion if discussion is closed
23
+ if @discussion.closed?
24
+ @discussion.update_attribute(:status, Discussion::STATUS.first)
25
+ end
26
+ end
27
+
28
+ flash[:notice] = 'Comment was successfully created.'
29
+ format.html {redirect_to category_discussion_path(@discussion.category, @discussion)}
30
+ else
31
+ @new_post = @post
32
+ @posts = existing_posts
33
+ format.html {render :template => "cornerstone/discussions/show"}
34
+ end
35
+ end
36
+ end
37
+
38
+ # GET /cornerstone/discussions/:discussion_id/posts/:id/edit
39
+ def edit
40
+ @post = Post.includes(:user, :discussion).find(params[:id])
41
+ raise Cornerstone::AccessDenied unless @post.created_by?(current_cornerstone_user)
42
+ @discussion = @post.discussion
43
+ respond_with(@discussion, @post)
44
+ end
45
+
46
+ # PUT /cornerstone/discussions/:discussion_id/posts/:id
47
+ def update
48
+ @post = Post.includes(:user, :discussion).find(params[:id])
49
+ raise Cornerstone::AccessDenied unless @post.created_by?(current_cornerstone_user)
50
+ @discussion = @post.discussion
51
+ flash[:notice] = "Post was successfully updated." if @post.update_attributes(params[:post])
52
+ respond_with(@discussion, @post, :location => category_discussion_path(@discussion.category, @discussion))
53
+ end
54
+
55
+ # DELETE /cornerstone/discussions/:discussion_id/posts/:id
56
+ def destroy
57
+ @post = Post.includes(:user, :discussion).find(params[:id])
58
+ raise Cornerstone::AccessDenied unless @post.created_by?(current_cornerstone_user)
59
+ @discussion = @post.discussion
60
+ flash[:notice] = "Post was successfully deleted." if @post.destroy
61
+ respond_with(@discussion, @post, :location => category_discussion_path(@discussion.category, @discussion))
62
+ end
63
+
64
+ end
65
+ end
66
+
File without changes
@@ -0,0 +1,5 @@
1
+ module Cornerstone
2
+ module ApplicationHelper
3
+ end
4
+ end
5
+
@@ -0,0 +1,16 @@
1
+ module Cornerstone
2
+ module DiscussionsHelper
3
+
4
+ # Returns details and links about the latest discussion for a given category
5
+ def latest_discussion_details(category)
6
+ if discussion = category.latest_discussion
7
+ render :partial => 'latest_discussion', :object => discussion,
8
+ :locals => {:category => category}
9
+ else
10
+ "N/A"
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+
@@ -0,0 +1,4 @@
1
+ module Cornerstone
2
+ module HelpHelper
3
+ end
4
+ end
@@ -0,0 +1,31 @@
1
+ module Cornerstone
2
+ class CornerstoneMailer < ActionMailer::Base
3
+ default from: Cornerstone::Config.mailer_from
4
+
5
+ # Email admins on new discussion - refer to post observer
6
+ def new_discussion(post, discussion)
7
+ @post = post
8
+ @discussion = discussion
9
+ mail :to => Cornerstone::Config.admin_emails
10
+ end
11
+
12
+ # Email user that created new discussion - refer to post observer
13
+ def new_discussion_user(post, discussion)
14
+ @post = post
15
+ @discussion = discussion
16
+ mail :to => post.author_email
17
+ end
18
+
19
+ # Email a single participant within a discussion - refer to post observer
20
+ def new_post(name, email, post, discussion)
21
+ @post = post
22
+ @discussion = discussion
23
+ @name = name
24
+
25
+ mail :to => email,
26
+ :subject => I18n.t('cornerstone.cornerstone_mailer.new_post.subject',
27
+ :topic => @discussion.subject)
28
+ end
29
+
30
+ end
31
+ end
File without changes
@@ -0,0 +1,20 @@
1
+ module Cornerstone
2
+ class Article < ActiveRecord::Base
3
+ # == CONSTANTS == #
4
+
5
+ # == ASSOCIATIONS == #
6
+ belongs_to :category
7
+
8
+ # == ACCESSIBILITY == #
9
+ # == SCOPES == #
10
+
11
+ # == VALIDATIONS == #
12
+ validates_presence_of :title, :body, :category
13
+
14
+ # == CALLBACKS == #
15
+ # == CLASS METHODS == #
16
+ # == INSTANCE METHODS == #
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,45 @@
1
+ module Cornerstone
2
+ class Category < ActiveRecord::Base
3
+
4
+ # == CONSTANTS == #
5
+ TYPES = ["Discussion", "Article"]
6
+
7
+ # == ASSOCIATIONS == #
8
+ has_many :discussions, :dependent => :destroy
9
+ has_many :articles, :dependent => :destroy
10
+
11
+ # == ACCESSIBILITY == #
12
+ attr_accessible :name, :category_type, :description
13
+
14
+ # == SCOPES == #
15
+
16
+ scope :discussions, lambda { where("cornerstone_categories.category_type = 'Discussion'") }
17
+ scope :articles, lambda { where("cornerstone_categories.category_type = 'Article'") }
18
+
19
+ # == VALIDATIONS == #
20
+ validates :name, :presence => true,
21
+ :length => {:maximum => 50}
22
+
23
+ validates :category_type, :inclusion => { :in => Cornerstone::Category::TYPES }
24
+
25
+ validates :description, :presence => true,
26
+ :length => {:maximum => 500}
27
+
28
+ # == CALLBACKS == #
29
+ # == CLASS METHODS == #
30
+
31
+ # == INSTANCE METHODS == #
32
+
33
+ # Provides the latest discussion created for this category
34
+ def latest_discussion
35
+ latest_discussions(1).first
36
+ end
37
+
38
+ # Provides the last 'num' discussions created for this category
39
+ def latest_discussions(num=nil)
40
+ Discussion.latest_for_category(self, num)
41
+ end
42
+
43
+ end
44
+ end
45
+
@@ -0,0 +1,90 @@
1
+ module Cornerstone
2
+ class Discussion < ActiveRecord::Base
3
+
4
+ # == CONSTANTS == #
5
+ STATUS = Cornerstone::Config.discussion_statuses
6
+
7
+ # == ASSOCIATIONS == #
8
+ belongs_to :category, :counter_cache => :item_count
9
+ # belongs_to 'user' also established by acts_as_cornerstone_user
10
+
11
+ has_many :posts, :dependent => :destroy
12
+ accepts_nested_attributes_for :posts
13
+
14
+ # == ACCESSIBILITY == #
15
+ attr_accessible :subject, :privte, :category_id, :posts_attributes
16
+
17
+ # == SCOPES == #
18
+ default_scope :order => "created_at DESC",
19
+ :conditions => {:privte => false}
20
+
21
+ scope :latest_for_category, lambda { |cat, num=5|
22
+ where(:category_id => cat.id)
23
+ .limit(num) }
24
+
25
+ # == VALIDATIONS == #
26
+ validates :subject, :presence => true,
27
+ :length => { :maximum => 50 }
28
+
29
+ validates :status, :inclusion => { :in => Cornerstone::Discussion::STATUS }
30
+
31
+ validates :category, :presence => true
32
+
33
+ # == CALLBACKS == #
34
+ after_save :set_latest_discussion, :on => :create
35
+
36
+ # == CLASS METHODS == #
37
+
38
+ # == INSTANCE METHODS == #
39
+ def author_name
40
+ self.posts.first.author_name
41
+ end
42
+
43
+ # returns true if discussion is 'closed'
44
+ def closed?
45
+ self.status == Cornerstone::Discussion::STATUS.last
46
+ end
47
+
48
+ # returns true if it was created by given user or if given user is an admin
49
+ def created_by?(check_user)
50
+ return false unless check_user.present?
51
+ return true if check_user.cornerstone_admin?
52
+ self.user && self.user == check_user
53
+ end
54
+
55
+ # returns an array of participants for the discussion
56
+ def participants(exclude_email=nil)
57
+ ps = []
58
+ self.posts.each do |p|
59
+ if p.author_name && p.author_email
60
+ ps << [p.author_name, p.author_email]
61
+ end
62
+ end
63
+ ps.delete_if{|p| p[1] == exclude_email}.uniq
64
+ end
65
+
66
+ # return a nicely formatted string for emailing
67
+ # i.e. Name <email_address>, Name <email_address>
68
+ def participants_email_list(exclude_email=nil)
69
+ participants(exclude_email).collect{ |p| "#{p[0]} <#{p[1]}>" }.join(", ")
70
+ end
71
+
72
+ #######
73
+ private
74
+ #######
75
+
76
+ # Update the category's latest discussion author/date
77
+ def set_latest_discussion
78
+ post = self.posts.first
79
+ if post
80
+ cat = self.category
81
+ cat.latest_discussion_author = post.author_name
82
+ cat.latest_discussion_date = Time.now.to_s(:db)
83
+ cat.save
84
+ end
85
+ end
86
+
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,103 @@
1
+ module Cornerstone
2
+ class Post < ActiveRecord::Base
3
+
4
+ belongs_to :discussion
5
+ # belongs_to 'user' also established by acts_as_cornerstone_user
6
+
7
+ # == CONSTANTS == #
8
+ # == ASSOCIATIONS == #
9
+ # == ACCESSIBILITY == #
10
+ attr_accessible :body, :name, :email
11
+
12
+ # == SCOPES == #
13
+ default_scope :order => "created_at ASC"
14
+
15
+ # == VALIDATIONS == #
16
+
17
+ validates :body, :presence => true,
18
+ :length => {:maximum => 3000}
19
+
20
+ validates :name, :presence => true,
21
+ :length => { :maximum => 50 },
22
+ :if => Proc.new { |p| !p.try(:user) }
23
+
24
+ validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i },
25
+ :if => Proc.new { |p| !p.try(:user) }
26
+
27
+ # == CALLBACKS == #
28
+ after_save :update_counter_cache
29
+ after_save :set_latest_post, :on => :create
30
+
31
+ after_destroy :update_counter_cache
32
+
33
+
34
+
35
+
36
+ # TODO: SANITATION ON NAME BODY EMAIL
37
+
38
+ # == CLASS METHODS == #
39
+
40
+
41
+ # == INSTANCE METHODS == #
42
+
43
+ # return the author name of the post
44
+ def author_name
45
+ #@cornerstone_name ||= anonymous_or_user_attr(:name)
46
+ anonymous_or_user_attr(:cornerstone_name)
47
+ end
48
+
49
+ # return the author email of the post
50
+ def author_email
51
+ #@cornerstone_email ||= anonymous_or_user_attr(:email)
52
+ anonymous_or_user_attr(:cornerstone_email)
53
+ end
54
+
55
+ # returns true if it was created by given user or if given user is an admin
56
+ def created_by?(check_user)
57
+ return false unless check_user.present?
58
+ return true if check_user.cornerstone_admin?
59
+ self.user && self.user == check_user
60
+ end
61
+
62
+ #######
63
+ private
64
+ #######
65
+
66
+ # Custom counter cache. Does not include the first post of a discussion.
67
+ def update_counter_cache
68
+ self.discussion.reply_count = Post.where(:discussion_id => self.discussion.id)
69
+ .count - 1
70
+ self.discussion.save
71
+ end
72
+
73
+ # Returns the requested attribute of the user if it exists, or post's attribute
74
+ def anonymous_or_user_attr(attr)
75
+ unless self.user_id.nil?
76
+ mthd = "user_#{attr.to_s}"
77
+ # TODO: rails caching is messing this relationship up.
78
+ # will .user work even if model name is something else. e.g. AdminUser ??
79
+ self.user.send(attr)
80
+ else
81
+ case attr
82
+ when :cornerstone_name
83
+ self.send(:name)
84
+ when :cornerstone_email
85
+ self.send(:email)
86
+ end
87
+ end
88
+ end
89
+
90
+ # Update the discussion's latest post author/date
91
+ def set_latest_post
92
+ discussion = self.discussion
93
+ if discussion
94
+ discussion.latest_post_author = self.author_name
95
+ discussion.latest_post_date = Time.now.to_s(:db)
96
+ discussion.save
97
+ end
98
+ end
99
+
100
+
101
+ end
102
+ end
103
+