@@ -0,0 +1,6 | |||||
|
1 | class Comment < ActiveRecord::Base | |||
|
2 | belongs_to :commented, :polymorphic => true, :counter_cache => true | |||
|
3 | belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' | |||
|
4 | ||||
|
5 | validates_presence_of :commented, :author, :comment | |||
|
6 | end |
@@ -0,0 +1,16 | |||||
|
1 | class CreateComments < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | create_table :comments do |t| | |||
|
4 | t.column :commented_type, :string, :limit => 30, :default => "", :null => false | |||
|
5 | t.column :commented_id, :integer, :default => 0, :null => false | |||
|
6 | t.column :author_id, :integer, :default => 0, :null => false | |||
|
7 | t.column :comment, :text, :default => "", :null => false | |||
|
8 | t.column :created_on, :datetime, :null => false | |||
|
9 | t.column :updated_on, :datetime, :null => false | |||
|
10 | end | |||
|
11 | end | |||
|
12 | ||||
|
13 | def self.down | |||
|
14 | drop_table :comments | |||
|
15 | end | |||
|
16 | end |
@@ -0,0 +1,9 | |||||
|
1 | class AddNewsCommentsCount < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | add_column :news, :comments_count, :integer, :default => 0, :null => false | |||
|
4 | end | |||
|
5 | ||||
|
6 | def self.down | |||
|
7 | remove_column :news, :comments_count | |||
|
8 | end | |||
|
9 | end |
@@ -0,0 +1,11 | |||||
|
1 | class AddCommentsPermissions < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | Permission.create :controller => "news", :action => "add_comment", :description => "label_comment_add", :sort => 1130, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
|
4 | Permission.create :controller => "news", :action => "destroy_comment", :description => "label_comment_delete", :sort => 1133, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
|
5 | end | |||
|
6 | ||||
|
7 | def self.down | |||
|
8 | Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'add_comment']).destroy | |||
|
9 | Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'destroy_comment']).destroy | |||
|
10 | end | |||
|
11 | end |
@@ -0,0 +1,10 | |||||
|
1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html | |||
|
2 | comments_001: | |||
|
3 | commented_type: News | |||
|
4 | commented_id: 1 | |||
|
5 | id: 1 | |||
|
6 | author_id: 1 | |||
|
7 | comment: my first comment | |||
|
8 | created_on: 2006-12-10 18:10:10 +01:00 | |||
|
9 | updated_on: 2006-12-10 18:10:10 +01:00 | |||
|
10 | No newline at end of file |
@@ -0,0 +1,30 | |||||
|
1 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
2 | ||||
|
3 | class CommentTest < Test::Unit::TestCase | |||
|
4 | fixtures :users, :news, :comments | |||
|
5 | ||||
|
6 | def setup | |||
|
7 | @jsmith = User.find(2) | |||
|
8 | @news = News.find(1) | |||
|
9 | end | |||
|
10 | ||||
|
11 | def test_create | |||
|
12 | comment = Comment.new(:commented => @news, :author => @jsmith, :comment => "my comment") | |||
|
13 | assert comment.save | |||
|
14 | @news.reload | |||
|
15 | assert_equal 2, @news.comments_count | |||
|
16 | end | |||
|
17 | ||||
|
18 | def test_validate | |||
|
19 | comment = Comment.new(:commented => @news) | |||
|
20 | assert !comment.save | |||
|
21 | assert_equal 2, comment.errors.length | |||
|
22 | end | |||
|
23 | ||||
|
24 | def test_destroy | |||
|
25 | comment = Comment.find(1) | |||
|
26 | assert comment.destroy | |||
|
27 | @news.reload | |||
|
28 | assert_equal 0, @news.comments_count | |||
|
29 | end | |||
|
30 | end |
@@ -27,7 +27,23 class NewsController < ApplicationController | |||||
27 | flash[:notice] = l(:notice_successful_update) |
|
27 | flash[:notice] = l(:notice_successful_update) | |
28 | redirect_to :action => 'show', :id => @news |
|
28 | redirect_to :action => 'show', :id => @news | |
29 | end |
|
29 | end | |
|
30 | end | |||
|
31 | ||||
|
32 | def add_comment | |||
|
33 | @comment = Comment.new(params[:comment]) | |||
|
34 | @comment.author = logged_in_user | |||
|
35 | if @news.comments << @comment | |||
|
36 | flash[:notice] = l(:label_comment_added) | |||
|
37 | redirect_to :action => 'show', :id => @news | |||
|
38 | else | |||
|
39 | render :action => 'show' | |||
|
40 | end | |||
30 | end |
|
41 | end | |
|
42 | ||||
|
43 | def destroy_comment | |||
|
44 | @news.comments.find(params[:comment_id]).destroy | |||
|
45 | redirect_to :action => 'show', :id => @news | |||
|
46 | end | |||
31 |
|
47 | |||
32 | def destroy |
|
48 | def destroy | |
33 | @news.destroy |
|
49 | @news.destroy |
@@ -18,6 +18,7 | |||||
18 | class News < ActiveRecord::Base |
|
18 | class News < ActiveRecord::Base | |
19 | belongs_to :project |
|
19 | belongs_to :project | |
20 | belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' |
|
20 | belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' | |
|
21 | has_many :comments, :as => :commented, :dependent => true, :order => "created_on" | |||
21 |
|
22 | |||
22 | validates_presence_of :title, :description |
|
23 | validates_presence_of :title, :description | |
23 |
|
24 |
@@ -13,4 +13,26 | |||||
13 | <% end %> |
|
13 | <% end %> | |
14 | </div> |
|
14 | </div> | |
15 |
|
15 | |||
16 | <%= link_to_if_authorized l(:button_edit), :controller => 'news', :action => 'edit', :id => @news %> |
|
16 | <p><%= link_to_if_authorized l(:button_edit), :controller => 'news', :action => 'edit', :id => @news %></p> | |
|
17 | ||||
|
18 | <div id="comments" style="margin-bottom:16px;"> | |||
|
19 | <h3><%= l(:label_comment_plural) %></h3> | |||
|
20 | <% @news.comments.each do |comment| %> | |||
|
21 | <% next if comment.new_record? %> | |||
|
22 | <h4><%= format_time(comment.created_on) %> - <%= comment.author.name %></h4> | |||
|
23 | <div style="float:right;"> | |||
|
24 | <small><%= link_to_if_authorized l(:button_delete), {:controller => 'news', :action => 'destroy_comment', :id => @news, :comment_id => comment}, :confirm => l(:text_are_you_sure), :post => true %></small> | |||
|
25 | </div> | |||
|
26 | <%= simple_format(auto_link(h comment.comment))%> | |||
|
27 | <% end if @news.comments_count > 0 %> | |||
|
28 | </div> | |||
|
29 | ||||
|
30 | <% if authorize_for 'news', 'add_comment' %> | |||
|
31 | <h3><%= l(:label_comment_add) %></h3> | |||
|
32 | <%= start_form_tag :action => 'add_comment', :id => @news %> | |||
|
33 | <%= error_messages_for 'comment' %> | |||
|
34 | <p><label for="comment_comment"><%= l(:field_comment) %></label><br /> | |||
|
35 | <%= text_area 'comment', 'comment', :cols => 60, :rows => 6 %></p> | |||
|
36 | <%= submit_tag l(:button_add) %> | |||
|
37 | <%= end_form_tag %> | |||
|
38 | <% end %> No newline at end of file |
@@ -6,7 +6,8 | |||||
6 | <% for news in @news %> |
|
6 | <% for news in @news %> | |
7 | <li><%= link_to news.title, :controller => 'news', :action => 'show', :id => news %><br /> |
|
7 | <li><%= link_to news.title, :controller => 'news', :action => 'show', :id => news %><br /> | |
8 | <% unless news.summary.empty? %><%= news.summary %><br /><% end %> |
|
8 | <% unless news.summary.empty? %><%= news.summary %><br /><% end %> | |
9 |
<em><%= news.author.name %>, <%= format_time(news.created_on) %></em><br /> |
|
9 | <em><%= news.author.name %>, <%= format_time(news.created_on) %></em><br /> | |
|
10 | <%= news.comments_count %> <%= lwr(:label_comment, news.comments_count).downcase %><br /> | |||
10 | </li> |
|
11 | </li> | |
11 | <% end %> |
|
12 | <% end %> | |
12 | </ul> |
|
13 | </ul> |
@@ -135,6 +135,7 field_onthefly: On-the-fly Benutzerkreation | |||||
135 | field_start_date: Beginn |
|
135 | field_start_date: Beginn | |
136 | field_done_ratio: %% Getan |
|
136 | field_done_ratio: %% Getan | |
137 | field_hide_mail: Mein email address verstecken |
|
137 | field_hide_mail: Mein email address verstecken | |
|
138 | field_comment: Anmerkung | |||
138 |
|
139 | |||
139 | label_user: Benutzer |
|
140 | label_user: Benutzer | |
140 | label_user_plural: Benutzer |
|
141 | label_user_plural: Benutzer | |
@@ -259,6 +260,11 label_internal: Intern | |||||
259 | label_last_changes: %d änderungen des Letzten |
|
260 | label_last_changes: %d änderungen des Letzten | |
260 | label_change_view_all: Alle änderungen ansehen |
|
261 | label_change_view_all: Alle änderungen ansehen | |
261 | label_personalize_page: Diese Seite personifizieren |
|
262 | label_personalize_page: Diese Seite personifizieren | |
|
263 | label_comment: Anmerkung | |||
|
264 | label_comment_plural: Anmerkungen | |||
|
265 | label_comment_add: Anmerkung addieren | |||
|
266 | label_comment_added: Anmerkung fügte hinzu | |||
|
267 | label_comment_delete: Anmerkungen löschen | |||
262 |
|
268 | |||
263 | button_login: Einloggen |
|
269 | button_login: Einloggen | |
264 | button_submit: Einreichen |
|
270 | button_submit: Einreichen |
@@ -135,6 +135,7 field_onthefly: On-the-fly user creation | |||||
135 | field_start_date: Start |
|
135 | field_start_date: Start | |
136 | field_done_ratio: %% Done |
|
136 | field_done_ratio: %% Done | |
137 | field_hide_mail: Hide my email address |
|
137 | field_hide_mail: Hide my email address | |
|
138 | field_comment: Comment | |||
138 |
|
139 | |||
139 | label_user: User |
|
140 | label_user: User | |
140 | label_user_plural: Users |
|
141 | label_user_plural: Users | |
@@ -259,6 +260,11 label_internal: Internal | |||||
259 | label_last_changes: last %d changes |
|
260 | label_last_changes: last %d changes | |
260 | label_change_view_all: View all changes |
|
261 | label_change_view_all: View all changes | |
261 | label_personalize_page: Personalize this page |
|
262 | label_personalize_page: Personalize this page | |
|
263 | label_comment: Comment | |||
|
264 | label_comment_plural: Comments | |||
|
265 | label_comment_add: Add a comment | |||
|
266 | label_comment_added: Comment added | |||
|
267 | label_comment_delete: Delete comments | |||
262 |
|
268 | |||
263 | button_login: Login |
|
269 | button_login: Login | |
264 | button_submit: Submit |
|
270 | button_submit: Submit |
@@ -135,6 +135,7 field_onthefly: Creación del usuario On-the-fly | |||||
135 | field_start_date: Comienzo |
|
135 | field_start_date: Comienzo | |
136 | field_done_ratio: %% Realizado |
|
136 | field_done_ratio: %% Realizado | |
137 | field_hide_mail: Ocultar mi email address |
|
137 | field_hide_mail: Ocultar mi email address | |
|
138 | field_comment: Comentario | |||
138 |
|
139 | |||
139 | label_user: Usuario |
|
140 | label_user: Usuario | |
140 | label_user_plural: Usuarios |
|
141 | label_user_plural: Usuarios | |
@@ -259,6 +260,11 label_internal: Interno | |||||
259 | label_last_changes: %d cambios del último |
|
260 | label_last_changes: %d cambios del último | |
260 | label_change_view_all: Ver todos los cambios |
|
261 | label_change_view_all: Ver todos los cambios | |
261 | label_personalize_page: Personalizar esta página |
|
262 | label_personalize_page: Personalizar esta página | |
|
263 | label_comment: Comentario | |||
|
264 | label_comment_plural: Comentarios | |||
|
265 | label_comment_add: Agregar un comentario | |||
|
266 | label_comment_added: Comentario agregó | |||
|
267 | label_comment_delete: Suprimir comentarios | |||
262 |
|
268 | |||
263 | button_login: Conexión |
|
269 | button_login: Conexión | |
264 | button_submit: Someter |
|
270 | button_submit: Someter |
@@ -136,6 +136,7 field_start_date: Début | |||||
136 | field_done_ratio: %% Réalisé |
|
136 | field_done_ratio: %% Réalisé | |
137 | field_auth_source: Mode d'authentification |
|
137 | field_auth_source: Mode d'authentification | |
138 | field_hide_mail: Cacher mon adresse mail |
|
138 | field_hide_mail: Cacher mon adresse mail | |
|
139 | field_comment: Commentaire | |||
139 |
|
140 | |||
140 | label_user: Utilisateur |
|
141 | label_user: Utilisateur | |
141 | label_user_plural: Utilisateurs |
|
142 | label_user_plural: Utilisateurs | |
@@ -260,6 +261,11 label_internal: Interne | |||||
260 | label_last_changes: %d derniers changements |
|
261 | label_last_changes: %d derniers changements | |
261 | label_change_view_all: Voir tous les changements |
|
262 | label_change_view_all: Voir tous les changements | |
262 | label_personalize_page: Personnaliser cette page |
|
263 | label_personalize_page: Personnaliser cette page | |
|
264 | label_comment: Commentaire | |||
|
265 | label_comment_plural: Commentaires | |||
|
266 | label_comment_add: Ajouter un commentaire | |||
|
267 | label_comment_added: Commentaire ajouté | |||
|
268 | label_comment_delete: Supprimer les commentaires | |||
263 |
|
269 | |||
264 | button_login: Connexion |
|
270 | button_login: Connexion | |
265 | button_submit: Soumettre |
|
271 | button_submit: Soumettre |
@@ -26,11 +26,11 begin | |||||
26 | manager.permissions = Permission.find(:all, :conditions => ["is_public=?", false]) |
|
26 | manager.permissions = Permission.find(:all, :conditions => ["is_public=?", false]) | |
27 |
|
27 | |||
28 | developper = Role.create :name => l(:default_role_developper) |
|
28 | developper = Role.create :name => l(:default_role_developper) | |
29 | perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057] |
|
29 | perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1130, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057] | |
30 | developper.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) |
|
30 | developper.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) | |
31 |
|
31 | |||
32 | reporter = Role.create :name => l(:default_role_reporter) |
|
32 | reporter = Role.create :name => l(:default_role_reporter) | |
33 | perms = [1050, 1060, 1070, 1057] |
|
33 | perms = [1050, 1060, 1070, 1057, 1130] | |
34 | reporter.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) |
|
34 | reporter.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) | |
35 |
|
35 | |||
36 | # trackers |
|
36 | # trackers |
@@ -446,7 +446,7 img.calendar-trigger { | |||||
446 | margin-left: 4px; |
|
446 | margin-left: 4px; | |
447 | } |
|
447 | } | |
448 |
|
448 | |||
449 | #history h4 { |
|
449 | #history h4, #comments h4 { | |
450 | font-size: 1em; |
|
450 | font-size: 1em; | |
451 | margin-bottom: 12px; |
|
451 | margin-bottom: 12px; | |
452 | margin-top: 20px; |
|
452 | margin-top: 20px; |
@@ -10,6 +10,7 news_001: | |||||
10 | Visit http://ecookbook.somenet.foo/ |
|
10 | Visit http://ecookbook.somenet.foo/ | |
11 | summary: First version was released... |
|
11 | summary: First version was released... | |
12 | author_id: 2 |
|
12 | author_id: 2 | |
|
13 | comments_count: 1 | |||
13 | news_002: |
|
14 | news_002: | |
14 | created_on: 2006-07-19 22:42:58 +02:00 |
|
15 | created_on: 2006-07-19 22:42:58 +02:00 | |
15 | project_id: 1 |
|
16 | project_id: 1 | |
@@ -18,3 +19,4 news_002: | |||||
18 | description: eCookbook 1.0 have downloaded 100,000 times |
|
19 | description: eCookbook 1.0 have downloaded 100,000 times | |
19 | summary: eCookbook 1.0 have downloaded 100,000 times |
|
20 | summary: eCookbook 1.0 have downloaded 100,000 times | |
20 | author_id: 2 |
|
21 | author_id: 2 | |
|
22 | comments_count: 0 |
General Comments 0
You need to be logged in to leave comments.
Login now