the_comments_ruby 2.3.3

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 (172) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.ruby-gemset.example +1 -0
  4. data/.ruby-version.example +1 -0
  5. data/.rvmrc.example +1 -0
  6. data/.travis.yml +5 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +338 -0
  10. data/Rakefile +1 -0
  11. data/app/assets/javascripts/the_comments.js.coffee +108 -0
  12. data/app/assets/javascripts/the_comments_manage.js.coffee +27 -0
  13. data/app/assets/stylesheets/the_comments.css.scss +248 -0
  14. data/app/controllers/_templates_/comments_controller.rb +44 -0
  15. data/app/controllers/concerns/the_comments/controller.rb +197 -0
  16. data/app/controllers/concerns/the_comments/view_token.rb +20 -0
  17. data/app/helpers/render_comments_tree_helper.rb +111 -0
  18. data/app/models/_templates_/comment.rb +38 -0
  19. data/app/models/concerns/the_comments/comment.rb +116 -0
  20. data/app/models/concerns/the_comments/comment_states.rb +80 -0
  21. data/app/models/concerns/the_comments/commentable.rb +69 -0
  22. data/app/models/concerns/the_comments/user.rb +56 -0
  23. data/app/views/the_comments/_tree.html.erb +3 -0
  24. data/app/views/the_comments/haml/_additional_info.html.haml +13 -0
  25. data/app/views/the_comments/haml/_comment.html.haml +1 -0
  26. data/app/views/the_comments/haml/_comment_body.html.haml +25 -0
  27. data/app/views/the_comments/haml/_comment_edit.html.haml +26 -0
  28. data/app/views/the_comments/haml/_form.html.haml +8 -0
  29. data/app/views/the_comments/haml/_guest_form.html.haml +22 -0
  30. data/app/views/the_comments/haml/_logined_form.html.haml +18 -0
  31. data/app/views/the_comments/haml/_manage_controls.html.haml +30 -0
  32. data/app/views/the_comments/haml/_sidebar.html.haml +9 -0
  33. data/app/views/the_comments/haml/_sidebar_admin.html.haml +12 -0
  34. data/app/views/the_comments/haml/_sidebar_backlink.html.haml +3 -0
  35. data/app/views/the_comments/haml/_sidebar_user.html.haml +29 -0
  36. data/app/views/the_comments/haml/_tree.html.haml +16 -0
  37. data/app/views/the_comments/haml/manage.html.haml +26 -0
  38. data/app/views/the_comments/slim/_additional_info.html.slim +13 -0
  39. data/app/views/the_comments/slim/_comment.html.slim +1 -0
  40. data/app/views/the_comments/slim/_comment_body.html.slim +24 -0
  41. data/app/views/the_comments/slim/_comment_edit.html.slim +26 -0
  42. data/app/views/the_comments/slim/_form.html.slim +8 -0
  43. data/app/views/the_comments/slim/_guest_form.html.slim +22 -0
  44. data/app/views/the_comments/slim/_logined_form.html.slim +18 -0
  45. data/app/views/the_comments/slim/_manage_controls.html.slim +30 -0
  46. data/app/views/the_comments/slim/_sidebar.html.slim +9 -0
  47. data/app/views/the_comments/slim/_sidebar_admin.html.slim +12 -0
  48. data/app/views/the_comments/slim/_sidebar_backlink.html.slim +3 -0
  49. data/app/views/the_comments/slim/_sidebar_user.html.slim +29 -0
  50. data/app/views/the_comments/slim/_tree.html.slim +16 -0
  51. data/app/views/the_comments/slim/index.html.slim +18 -0
  52. data/app/views/the_comments/slim/manage.html.slim +26 -0
  53. data/app/views/the_comments/slim/my_comments.html.slim +28 -0
  54. data/config/initializers/the_comments.rb +14 -0
  55. data/config/locales/en.yml +68 -0
  56. data/config/locales/ru.yml +71 -0
  57. data/config/routes.rb +38 -0
  58. data/db/migrate/20130101010101_the_comments_change_user.rb +18 -0
  59. data/db/migrate/20130101010102_the_comments_create_comments.rb +50 -0
  60. data/db/migrate/20130101010103_the_comments_change_commentable.rb +13 -0
  61. data/docs/admin_ui_installation.md +145 -0
  62. data/docs/advanced_installation.md +185 -0
  63. data/docs/comment_api.md +58 -0
  64. data/docs/commentable_api.md +59 -0
  65. data/docs/config_file.md +27 -0
  66. data/docs/content_preprocessors.md +73 -0
  67. data/docs/customazation_of_views.md +30 -0
  68. data/docs/denormalization_and_recent_comments.md +40 -0
  69. data/docs/documentation.md +29 -0
  70. data/docs/generators.md +74 -0
  71. data/docs/pagination.md +123 -0
  72. data/docs/routes.md +77 -0
  73. data/docs/screencast.jpg +0 -0
  74. data/docs/the_comments.jpg +0 -0
  75. data/docs/the_comments_view_1.gif +0 -0
  76. data/docs/the_comments_view_2.gif +0 -0
  77. data/docs/the_comments_view_3.gif +0 -0
  78. data/docs/the_comments_view_4.gif +0 -0
  79. data/docs/the_comments_view_5.gif +0 -0
  80. data/docs/user_api.md +75 -0
  81. data/docs/what_is_comcoms.md +63 -0
  82. data/docs/whats_wrong_with_other_gems.md +28 -0
  83. data/docs/where_is_example_application.md +37 -0
  84. data/gem_version.rb +3 -0
  85. data/lib/generators/the_comments/USAGE +44 -0
  86. data/lib/generators/the_comments/the_comments_generator.rb +56 -0
  87. data/lib/generators/the_comments/views_generator.rb +79 -0
  88. data/lib/the_comments/config.rb +37 -0
  89. data/lib/the_comments/version.rb +1 -0
  90. data/lib/the_comments.rb +28 -0
  91. data/spec/dummy_app/.gitignore +18 -0
  92. data/spec/dummy_app/.rspec +1 -0
  93. data/spec/dummy_app/Gemfile +43 -0
  94. data/spec/dummy_app/README.md +33 -0
  95. data/spec/dummy_app/Rakefile +6 -0
  96. data/spec/dummy_app/app/assets/images/.keep +0 -0
  97. data/spec/dummy_app/app/assets/javascripts/admin_panel.js +5 -0
  98. data/spec/dummy_app/app/assets/javascripts/application.js +16 -0
  99. data/spec/dummy_app/app/assets/stylesheets/admin_panel.css +3 -0
  100. data/spec/dummy_app/app/assets/stylesheets/app.css.scss +4 -0
  101. data/spec/dummy_app/app/assets/stylesheets/application.css +16 -0
  102. data/spec/dummy_app/app/controllers/application_controller.rb +7 -0
  103. data/spec/dummy_app/app/controllers/comments_controller.rb +28 -0
  104. data/spec/dummy_app/app/controllers/concerns/.keep +0 -0
  105. data/spec/dummy_app/app/controllers/posts_controller.rb +13 -0
  106. data/spec/dummy_app/app/controllers/users_controller.rb +7 -0
  107. data/spec/dummy_app/app/helpers/application_helper.rb +2 -0
  108. data/spec/dummy_app/app/mailers/.keep +0 -0
  109. data/spec/dummy_app/app/models/.keep +0 -0
  110. data/spec/dummy_app/app/models/comment.rb +32 -0
  111. data/spec/dummy_app/app/models/concerns/.keep +0 -0
  112. data/spec/dummy_app/app/models/post.rb +17 -0
  113. data/spec/dummy_app/app/models/user.rb +21 -0
  114. data/spec/dummy_app/app/views/layouts/admin.html.haml +25 -0
  115. data/spec/dummy_app/app/views/layouts/application.html.haml +20 -0
  116. data/spec/dummy_app/app/views/posts/index.html.haml +22 -0
  117. data/spec/dummy_app/app/views/posts/show.html.haml +7 -0
  118. data/spec/dummy_app/bin/bundle +3 -0
  119. data/spec/dummy_app/bin/rails +4 -0
  120. data/spec/dummy_app/bin/rake +4 -0
  121. data/spec/dummy_app/config/application.rb +23 -0
  122. data/spec/dummy_app/config/boot.rb +4 -0
  123. data/spec/dummy_app/config/database.yml +11 -0
  124. data/spec/dummy_app/config/environment.rb +5 -0
  125. data/spec/dummy_app/config/environments/development.rb +29 -0
  126. data/spec/dummy_app/config/environments/production.rb +80 -0
  127. data/spec/dummy_app/config/environments/test.rb +36 -0
  128. data/spec/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
  129. data/spec/dummy_app/config/initializers/filter_parameter_logging.rb +4 -0
  130. data/spec/dummy_app/config/initializers/inflections.rb +16 -0
  131. data/spec/dummy_app/config/initializers/mime_types.rb +5 -0
  132. data/spec/dummy_app/config/initializers/secret_token.rb +12 -0
  133. data/spec/dummy_app/config/initializers/session_store.rb +3 -0
  134. data/spec/dummy_app/config/initializers/sorcery.rb +437 -0
  135. data/spec/dummy_app/config/initializers/the_comments.rb +14 -0
  136. data/spec/dummy_app/config/initializers/wrap_parameters.rb +14 -0
  137. data/spec/dummy_app/config/locales/en.yml +23 -0
  138. data/spec/dummy_app/config/routes.rb +19 -0
  139. data/spec/dummy_app/config.ru +4 -0
  140. data/spec/dummy_app/db/migrate/20130712061503_sorcery_core.rb +16 -0
  141. data/spec/dummy_app/db/migrate/20130712065951_create_posts.rb +11 -0
  142. data/spec/dummy_app/db/migrate/20131027185332_change_user.the_comments_engine.rb +19 -0
  143. data/spec/dummy_app/db/migrate/20131027185333_create_comments.the_comments_engine.rb +51 -0
  144. data/spec/dummy_app/db/migrate/20131027185334_change_commentable.the_comments_engine.rb +14 -0
  145. data/spec/dummy_app/db/schema.rb +74 -0
  146. data/spec/dummy_app/db/seeds.rb +42 -0
  147. data/spec/dummy_app/lib/assets/.keep +0 -0
  148. data/spec/dummy_app/lib/tasks/.keep +0 -0
  149. data/spec/dummy_app/lib/tasks/app_bootstrap.rake +15 -0
  150. data/spec/dummy_app/log/.keep +0 -0
  151. data/spec/dummy_app/public/404.html +58 -0
  152. data/spec/dummy_app/public/422.html +58 -0
  153. data/spec/dummy_app/public/500.html +57 -0
  154. data/spec/dummy_app/public/favicon.ico +0 -0
  155. data/spec/dummy_app/public/robots.txt +5 -0
  156. data/spec/dummy_app/spec/factories/post.rb +6 -0
  157. data/spec/dummy_app/spec/factories/user.rb +6 -0
  158. data/spec/dummy_app/spec/models/user_counters_spec.rb +339 -0
  159. data/spec/dummy_app/spec/spec_helper.rb +29 -0
  160. data/spec/dummy_app/test/controllers/.keep +0 -0
  161. data/spec/dummy_app/test/fixtures/.keep +0 -0
  162. data/spec/dummy_app/test/helpers/.keep +0 -0
  163. data/spec/dummy_app/test/integration/.keep +0 -0
  164. data/spec/dummy_app/test/mailers/.keep +0 -0
  165. data/spec/dummy_app/test/models/.keep +0 -0
  166. data/spec/dummy_app/test/test_helper.rb +15 -0
  167. data/spec/dummy_app/vendor/assets/javascripts/.keep +0 -0
  168. data/spec/dummy_app/vendor/assets/stylesheets/.keep +0 -0
  169. data/the_comments.gemspec +25 -0
  170. data/the_comments.yml.teamocil.example +11 -0
  171. data/views_converter.rb +16 -0
  172. metadata +333 -0
@@ -0,0 +1,185 @@
1
+ ←   [documentation](documentation.md)
2
+
3
+ ## Advanced Installation
4
+
5
+ ### 1. Gems install
6
+
7
+ **Gemfile**
8
+
9
+ ```ruby
10
+ gem 'the_comments', "~> 2.0"
11
+
12
+ gem 'haml' # or gem 'slim'
13
+ gem 'awesome_nested_set' # or same gem
14
+ ```
15
+
16
+ **Bundle**
17
+
18
+ ```
19
+ bundle
20
+ ```
21
+
22
+ ### 2. Migrations install
23
+
24
+ **Copy migrations**
25
+
26
+ ```
27
+ rake the_comments_engine:install:migrations
28
+ ```
29
+
30
+ Will create:
31
+
32
+ * xxxxx_change_user.rb
33
+ * xxxxx_create_comments.rb
34
+ * xxxxx_change_commentable.rb
35
+
36
+ :warning:   **Open and change xxxxx_change_commentable.rb migration**
37
+
38
+ ```ruby
39
+ class ChangeCommentable < ActiveRecord::Migration
40
+ def change
41
+ # Additional fields to Commentable Models
42
+ # [:posts, :articles, ... ]
43
+
44
+ # There is only Post model is commentable
45
+ [:posts].each do |table_name|
46
+ change_table table_name do |t|
47
+ t.integer :draft_comments_count, default: 0
48
+ t.integer :published_comments_count, default: 0
49
+ t.integer :deleted_comments_count, default: 0
50
+ end
51
+ end
52
+ end
53
+ end
54
+ ```
55
+
56
+ **Invoke migrations**
57
+
58
+ ```
59
+ rake db:migrate
60
+ ```
61
+
62
+ ### 3. Code install
63
+
64
+ ```ruby
65
+ rails g the_comments install
66
+ ```
67
+
68
+ Will create:
69
+
70
+ * config/initializers/the_comments.rb
71
+ * app/controllers/comments_controller.rb
72
+ * app/models/comment.rb
73
+
74
+ :warning: &nbsp; **Open each file and follow an instructions**
75
+
76
+ ### 4. Models modifictions
77
+
78
+ **app/models/user.rb**
79
+
80
+ ```ruby
81
+ class User < ActiveRecord::Base
82
+ include TheComments::User
83
+
84
+ has_many :posts
85
+
86
+ # Your way to define privileged users
87
+ def admin?
88
+ self == User.first
89
+ end
90
+
91
+ # Required TheComments methods for users restrictions
92
+ def comments_admin?
93
+ admin?
94
+ end
95
+
96
+ def comments_moderator? comment
97
+ id == comment.holder_id
98
+ end
99
+ end
100
+ ```
101
+
102
+ **app/models/post.rb**
103
+
104
+ ```ruby
105
+ class Post < ActiveRecord::Base
106
+ include TheComments::Commentable
107
+
108
+ belongs_to :user
109
+
110
+ # Denormalization methods
111
+ # Migration: t.string :title
112
+ # => "My new awesome post"
113
+ def commentable_title
114
+ try(:title) || "Undefined post title"
115
+ end
116
+
117
+ # => your way to build URL
118
+ # => "/posts/254"
119
+ def commentable_url
120
+ ['', self.class.to_s.tableize, id].join('/')
121
+ end
122
+
123
+ # gem 'state_machine'
124
+ # Migration: t.string :state
125
+ # => "published" | "draft" | "deleted"
126
+ def commentable_state
127
+ try(:state) || "published"
128
+ end
129
+ end
130
+ ```
131
+
132
+ ### 5. Mount Engine routes
133
+
134
+ **config/routes.rb**
135
+
136
+ ```ruby
137
+ MyApp::Application.routes.draw do
138
+ root 'posts#index'
139
+ resources :posts
140
+
141
+ # ...
142
+
143
+ # TheComments routes
144
+ concern :user_comments, TheComments::UserRoutes.new
145
+ concern :admin_comments, TheComments::AdminRoutes.new
146
+ resources :comments, concerns: [:user_comments, :admin_comments]
147
+ end
148
+ ```
149
+
150
+ Please, read [documentation](docs/documentation.md) to learn more
151
+
152
+ ### 6. Assets install
153
+
154
+ **app/assets/stylesheets/application.css**
155
+
156
+ ```css
157
+ /*
158
+ *= require the_comments
159
+ */
160
+ ```
161
+
162
+ **app/assets/javascripts/application.js**
163
+
164
+ ```js
165
+ //= require the_comments
166
+ ```
167
+
168
+ ### 7. Controller code example
169
+
170
+ **app/controllers/posts_controllers.rb**
171
+
172
+ ```ruby
173
+ def show
174
+ @post = Post.find params[:id]
175
+ @comments = @post.comments.with_state([:draft, :published])
176
+ end
177
+ ```
178
+
179
+ ### 8. View code example
180
+
181
+ **app/views/posts/show.html.haml**
182
+
183
+ ```haml
184
+ = render partial: 'the_comments/tree', locals: { commentable: @post, comments_tree: @comments }
185
+ ```
@@ -0,0 +1,58 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ### Comment API
4
+
5
+ ```ruby
6
+ @comment = Comment.last
7
+
8
+ # Comment creator, can be nil (for Guest)
9
+ @comment.user # => User
10
+
11
+ # Comment holder
12
+ # Owner of commentable object
13
+ # shouldn't be nil, should be defined on create
14
+ @comment.holder # => User
15
+
16
+ # Commentable object
17
+ @comment.commentable # => Post
18
+
19
+ # Raw user input
20
+ @comment.raw_content
21
+
22
+ # Processed user input
23
+ # method *prepare_content* should be redefined by developer
24
+ @comment.content
25
+
26
+ # Denormalization fields
27
+ @comment.commentable_title # => "Harum sint error odit."
28
+ @comment.commentable_url # => "/posts/7"
29
+ @comment.commentable_state # => "published"
30
+
31
+ # Stat info from request
32
+ # Can be used for spam detection
33
+ @comment.user_agent # => Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10
34
+ @comment.tolerance_time # => 5 (secs)
35
+ @comment.referer # => localhost:3000/post/7
36
+ @comment.ip # => 192.168.0.12
37
+
38
+ # State
39
+ @comment.state # => draft | published | deleted
40
+
41
+ # Spam flag
42
+ @comment.spam # => true
43
+
44
+ # Alias for *mark_as_spam*
45
+ @comment.to_spam
46
+
47
+ # mark this comment and all descendants as spam/not spam
48
+ @comment.mark_as_spam
49
+ @comment.mark_as_not_spam
50
+
51
+ # Comment's creator avatar
52
+ # this method can be redefined by developer
53
+ @comment.avatar_url # => "https://2.gravatar.com/avatar/015e ... 2f05?s=42&d=https://identicons.github.com/AVATAR.png"
54
+
55
+ # Anchor of comment
56
+ # this method can be redefined by developer
57
+ @comment.anchor # => b58020
58
+ ```
@@ -0,0 +1,59 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ### Commentable API
4
+
5
+ ```ruby
6
+ class Post < ActiveRecord::Base
7
+ include TheCommentsCommentable
8
+
9
+ belongs_to :user
10
+
11
+ def commentable_title
12
+ try(:title) || "Undefined title"
13
+ end
14
+
15
+ def commentable_url
16
+ ['', self.class.to_s.tableize, id].join('/')
17
+ end
18
+
19
+ def commentable_state
20
+ try(:state) || "published"
21
+ end
22
+ end
23
+ ```
24
+
25
+ ```ruby
26
+ @post = Post.last
27
+
28
+ # Post owner
29
+ @post.user # => User
30
+
31
+ # All comments for commentable object
32
+ @post.comments # => ActiveRecord:Collection
33
+
34
+ # Cache counters
35
+ @post.draft_comments_count # => 1
36
+ @post.published_comments_count # => 2
37
+ @post.deleted_comments_count # => 0
38
+
39
+ # equal values with direct request to database
40
+ @post.comments.with_state([:draft]).count # => 1
41
+ @post.comments.with_state([:published]).count # => 2
42
+ @post.comments.with_state([:deleted]).count # => 0
43
+
44
+ # Alias for:
45
+ # draft_comments_count + published_comments_count
46
+ @post.comments_sum # => 3
47
+
48
+ # Spam comments
49
+ @post.comments.where(spam: true) # => ActiveRecord::Relation
50
+
51
+ # recalculate cache counters
52
+ @post.recalculate_comments_counters!
53
+
54
+ # Default Denormalization methods
55
+ # should be redefined by developer
56
+ @post.commentable_title => "Maiores eos rerum numquam aut."
57
+ @post.commentable_url => "/posts/9"
58
+ @post.commentable_state => "published"
59
+ ```
@@ -0,0 +1,27 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ### TheComments config
4
+
5
+ Following rails generator will copy default config file into your application
6
+
7
+ ```ruby
8
+ bundle exec rails g the_comments config
9
+ ```
10
+
11
+ **config/initializers/the_comments.rb**
12
+
13
+ ```ruby
14
+ # TheComments.config.param_name => value
15
+
16
+ TheComments.configure do |config|
17
+ config.max_reply_depth = 3 # comments tree depth
18
+ config.tolerance_time = 5 # sec - after this delay user can post a comment
19
+ config.default_state = :draft # default state for comment
20
+ config.default_owner_state = :published # default state for comment for Moderator
21
+ config.empty_inputs = [:commentBody] # array of spam trap fields
22
+ config.default_title = 'Undefined title' # default commentable_title for denormalization
23
+
24
+ config.empty_trap_protection = true
25
+ config.tolerance_time_protection = true
26
+ end
27
+ ```
@@ -0,0 +1,73 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ### Text preprocessors
4
+
5
+ TheComments designed for using with text preprocessors: Textile, Markdown, Sanitize, Coderay etc.
6
+
7
+ That is why Comment model has 2 fields for user input: **raw_content** and **content**
8
+
9
+ ```ruby
10
+ class CreateComments < ActiveRecord::Migration
11
+ def change
12
+ create_table :comments do |t|
13
+ # ...
14
+
15
+ t.text :raw_content
16
+ t.text :content
17
+
18
+ # ...
19
+ end
20
+ end
21
+ end
22
+ ```
23
+
24
+ **raw_content** - field with original user's input
25
+
26
+ **content** - field with processed user's input
27
+
28
+ <hr>
29
+
30
+ **before_save :prepare_content** - provides processing of raw user's input
31
+
32
+ By default **prepare_content** looks like this:
33
+
34
+ ```ruby
35
+ def prepare_content
36
+ self.content = self.raw_content
37
+ end
38
+ ```
39
+
40
+ I think every developer should redefine this behaviour. To do this you should to use following instructions.
41
+
42
+ ### Comment Model customization
43
+
44
+ invoke TheComments generator
45
+
46
+ ```ruby
47
+ bundle exec rails g the_comments models
48
+ ```
49
+
50
+ This will create **app/models/comment.rb**
51
+
52
+ ```ruby
53
+ class Comment < ActiveRecord::Base
54
+ include TheCommentsBase
55
+
56
+ # ---------------------------------------------------
57
+ # Define your filters for content
58
+ # Expample for: gem 'RedCloth', gem 'sanitize'
59
+ # your personal SmilesProcessor
60
+
61
+ # def prepare_content
62
+ # text = self.raw_content
63
+ # text = RedCloth.new(text).to_html
64
+ # text = SmilesProcessor.new(text)
65
+ # text = Sanitize.clean(text, Sanitize::Config::RELAXED)
66
+ # self.content = text
67
+ # end
68
+ # ---------------------------------------------------
69
+ end
70
+ ```
71
+
72
+ Just redefine **prepare_content** for your purposes
73
+
@@ -0,0 +1,30 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ## Customization
4
+
5
+ You can use **rails generators** for copy files into your Application. After that you can customize almost everything
6
+
7
+ Generators list:
8
+
9
+ ```ruby
10
+ bundle exec rails g the_comments --help
11
+ ```
12
+
13
+ ### Customization of views
14
+
15
+ Copy View files for customization:
16
+
17
+ ```ruby
18
+ bundle exec rails g the_comments:views assets
19
+ bundle exec rails g the_comments:views views
20
+ ```
21
+
22
+ ### Customization of comments tree
23
+
24
+ Copy Helper file for tree customization:
25
+
26
+ ```ruby
27
+ bundle exec rails g the_comments:views helper
28
+ ```
29
+
30
+ For more info read [TheSortableTree doc](https://github.com/the-teacher/the_sortable_tree)
@@ -0,0 +1,40 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ## Denormalization
4
+
5
+ For building of Recent comments list (for polymorphic relationship) we need to have many additional requests to database. It's classic problem of polymorphic comments.
6
+
7
+ I use denormalization of commentable objects to solve this problem.
8
+
9
+ My practice shows - We need 3 denormalized fields into comment for (request-free) building of recent comments list:
10
+
11
+ <img src="https://raw.github.com/the-teacher/the_comments/master/docs/the_comments_view_5.gif" alt="the_comments">
12
+
13
+ * **Comment#commentable_title** - for example: "My first post about Ruby On Rails"
14
+ * **Comment#commentable_url** - for example: "/posts/1-my-first-post-about-ruby-on-rails"
15
+ * **Comment#commentable_state** - for example: "draft"
16
+
17
+ That is why any **Commentable Model should have few methods** to provide denormalization for Comments.
18
+
19
+ ## Recent comments building
20
+
21
+ Denormalization makes building of Recent comments (for polymorphic relationship) very easy!
22
+
23
+ Controller:
24
+
25
+ ```ruby
26
+ @comments = Comment.with_state(:published)
27
+ .where(commentable_state: [:published])
28
+ .order('created_at DESC')
29
+ .page(params[:page])
30
+ ```
31
+
32
+ View:
33
+
34
+ ```ruby
35
+ - @comments.each do |comment|
36
+ %div
37
+ %p= comment.commentable_title
38
+ %p= link_to comment.commentable_title, comment.commentable_url
39
+ %p= comment.content
40
+ ```
@@ -0,0 +1,29 @@
1
+ #### INSTALLATION
2
+ * :white_check_mark: &nbsp; [ADVANCED INSTALLATION](advanced_installation.md)
3
+ * :white_check_mark: &nbsp; [ADMIN UI INSTALLATION](admin_ui_installation.md)
4
+ * :white_check_mark: &nbsp; [Routing](routes.md)
5
+ * :white_check_mark: &nbsp; [Generators](generators.md)
6
+
7
+ #### API
8
+ * :white_check_mark: &nbsp; [User API](user_api.md)
9
+ * :white_check_mark: &nbsp; [Comment API](comment_api.md)
10
+ * :white_check_mark: &nbsp; [Commentable API](commentable_api.md)
11
+
12
+ #### Understanding
13
+ * :white_check_mark: &nbsp; [What is ComComs?](what_is_comcoms.md)
14
+ * :white_check_mark: &nbsp; [Denormalization and Recent comments](denormalization_and_recent_comments.md)
15
+ * :white_check_mark: &nbsp; [What's wrong with other gems?](whats_wrong_with_other_gems.md)
16
+ * :white_check_mark: &nbsp; [Why TheComments is better than others gems?](whats_wrong_with_other_gems.md#why-thecomments-is-better-than-others-gems)
17
+
18
+ #### Customazation
19
+ * :white_check_mark: &nbsp; [Views](customazation_of_views.md)
20
+ * :white_check_mark: &nbsp; [Text Preprocessors - Sanitize, Markdown etc.](content_preprocessors.md)
21
+
22
+ #### Configuration
23
+ * :white_check_mark: &nbsp; [the_comments.rb config file](config_file.md)
24
+
25
+ #### Q&A
26
+ * :white_check_mark: &nbsp; [I want not to use kaminari for Admin UI](pagination.md)
27
+ * :white_check_mark: &nbsp; [Where is example application?](where_is_example_application.md)
28
+ * :white_check_mark: &nbsp; [How can I run tests?](where_is_example_application.md#run-tests)
29
+
@@ -0,0 +1,74 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ## Generators
4
+
5
+ ```ruby
6
+ rails g the_comments NAME
7
+ rails g the_comments:views NAME
8
+ ```
9
+
10
+ #### Migrations
11
+
12
+ ```ruby
13
+ rake the_comments_engine:install:migrations
14
+ ```
15
+
16
+ ### Full list
17
+
18
+ ```ruby
19
+ rails g the_comments --help
20
+ ```
21
+
22
+ #### Main
23
+
24
+ ```ruby
25
+ rails g the_comments install
26
+ ```
27
+
28
+ This will create:
29
+
30
+ * config/initializers/the_comments.rb
31
+ * app/controllers/comments_controller.rb
32
+ * app/models/comment.rb
33
+
34
+ #### Controllers
35
+
36
+ ```ruby
37
+ rails g the_comments controllers
38
+ ```
39
+
40
+ This will create:
41
+
42
+ * app/controllers/comments_controller.rb
43
+
44
+ #### Models
45
+
46
+ ```ruby
47
+ rails g the_comments models
48
+ ```
49
+
50
+ This will create:
51
+
52
+ * app/models/comment.rb
53
+
54
+ #### Config
55
+
56
+ ```ruby
57
+ rails g the_comments config
58
+ ```
59
+
60
+ #### Locals
61
+
62
+ ```ruby
63
+ rails g the_comments locales
64
+ ```
65
+
66
+ #### Views
67
+
68
+ ```ruby
69
+ rails g the_comments:views js
70
+ rails g the_comments:views css
71
+ rails g the_comments:views assets
72
+ rails g the_comments:views helper
73
+ rails g the_comments:views views
74
+ ```
@@ -0,0 +1,123 @@
1
+ &larr; &nbsp; [documentation](documentation.md)
2
+
3
+ ## I want not to use kaminari for Admin UI
4
+
5
+ By default we use Kaminari pagination for Admin UI.
6
+
7
+ But you can change this. For example, your **comments_controller.rb** looks like this:
8
+
9
+ **app/controllers/comments_controller.rb**
10
+
11
+ ```ruby
12
+ class CommentsController < ApplicationController
13
+ # layout 'admin'
14
+
15
+ # Define your restrict methods and use them like this:
16
+ #
17
+ # before_action :user_required, except: %w[index create]
18
+ # before_action :owner_required, except: %w[index create]
19
+ # before_action :admin_required, only: %w[total_draft total_published total_deleted total_spam]
20
+
21
+ include TheComments::Controller
22
+
23
+ # >>> include TheComments::Controller <<<
24
+ # (!) Almost all methods based on *current_user* method
25
+ #
26
+ # 1. Controller's public methods list:
27
+ # You can redifine it for your purposes
28
+ # public
29
+ # %w[ manage index create edit update ]
30
+ # %w[ my_comments my_draft my_published ]
31
+ # %w[ draft published deleted spam ]
32
+ # %w[ to_draft to_published to_deleted to_spam ]
33
+ # %w[ total_draft total_published total_deleted total_spam ]
34
+ #
35
+ #
36
+ # 2. Controller's private methods list:
37
+ # You can redifine it for your purposes
38
+ #
39
+ # private
40
+ # %w[ comment_template comment_partial ]
41
+ # %w[ denormalized_fields request_data_for_comment define_commentable ]
42
+ # %w[ comment_params patch_comment_params ]
43
+ # %w[ ajax_requests_required cookies_required ]
44
+ # %w[ empty_trap_required tolerance_time_required ]
45
+
46
+ # KAMINARI pagination:
47
+ # following methods based on gem "kaminari"
48
+ # You should redefine them if you use something else
49
+ #
50
+ # public
51
+ # %w[ manage index edit ]
52
+ # %w[ draft published deleted spam ]
53
+ # %w[ my_comments my_draft my_published ]
54
+ # %w[ total_draft total_published total_deleted total_spam ]
55
+ end
56
+ ```
57
+
58
+ There is we can see comments about kaminari. So, we can try to change it.
59
+
60
+ There is example how it can be in your real app:
61
+
62
+ ```ruby
63
+ class CommentsController < ApplicationController
64
+ layout 'admin'
65
+
66
+ before_action :user_required, except: %w[index create]
67
+ before_action :owner_required, except: %w[index create]
68
+ before_action :admin_required, only: %w[total_draft total_published total_deleted total_spam]
69
+
70
+ include TheComments::Controller
71
+
72
+ public
73
+
74
+ def index
75
+ @comments = ::Comment.with_state(:published).recent.super_paginator(params)
76
+ render comment_template(:index)
77
+ end
78
+
79
+ def manage
80
+ @comments = current_user.comcoms.active.recent.super_paginator(params)
81
+ render comment_template(:manage)
82
+ end
83
+
84
+ def my_comments
85
+ @comments = current_user.my_comments.active.recent.super_paginator(params)
86
+ render comment_template(:my_comments)
87
+ end
88
+
89
+ def edit
90
+ @comments = current_user.comcoms.where(id: params[:id]).super_paginator(params)
91
+ render comment_template(:manage)
92
+ end
93
+
94
+ %w[draft published deleted].each do |state|
95
+ define_method "#{state}" do
96
+ @comments = current_user.comcoms.with_state(state).recent.super_paginator(params)
97
+ render comment_template(:manage)
98
+ end
99
+
100
+ define_method "total_#{state}" do
101
+ @comments = ::Comment.with_state(state).recent.super_paginator(params)
102
+ render comment_template(:manage)
103
+ end
104
+
105
+ unless state == 'deleted'
106
+ define_method "my_#{state}" do
107
+ @comments = current_user.my_comments.with_state(state).recent.super_paginator(params)
108
+ render comment_template(:my_comments)
109
+ end
110
+ end
111
+ end
112
+
113
+ def spam
114
+ @comments = current_user.comcoms.where(spam: true).recent.super_paginator(params)
115
+ render comment_template(:manage)
116
+ end
117
+
118
+ def total_spam
119
+ @comments = ::Comment.where(spam: true).recent.super_paginator(params)
120
+ render comment_template(:manage)
121
+ end
122
+ end
123
+ ```