Commit bd3e6f9c052bc450b10808d22df84a821d02daea

Authored by Arthur Esposte
1 parent 3f63e993
Exists in tests

TEMP

app/models/comment.rb
@@ -37,6 +37,9 @@ class Comment < ActiveRecord::Base @@ -37,6 +37,9 @@ class Comment < ActiveRecord::Base
37 37
38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation' 38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
39 39
  40 + # TODO
  41 + # create migration to create total_votes fields
  42 + # see vote_fu/README.markdown
40 acts_as_voteable 43 acts_as_voteable
41 44
42 def comment_root 45 def comment_root
features/step_definitions/noosfero_steps.rb
@@ -91,10 +91,10 @@ Given /^the following blocks$/ do |table| @@ -91,10 +91,10 @@ Given /^the following blocks$/ do |table|
91 owner_type = item.delete('owner') 91 owner_type = item.delete('owner')
92 owner = owner_type == 'environment' ? Environment.default : Profile[owner_type] 92 owner = owner_type == 'environment' ? Environment.default : Profile[owner_type]
93 if owner.boxes.empty? 93 if owner.boxes.empty?
94 - owner.boxes<< Box.new 94 + owner.boxes << Box.new
95 owner.boxes.first.blocks << MainBlock.new 95 owner.boxes.first.blocks << MainBlock.new
96 end 96 end
97 - box = owner.boxes.where(:position => 3).first 97 + box = owner.boxes.first
98 klass.constantize.create!(item.merge(:box => box)) 98 klass.constantize.create!(item.merge(:box => box))
99 end 99 end
100 end 100 end
public/javascripts/media-panel.js
1 -var file_id = 1;  
2 -  
3 -jQuery('.view-all-media').on('click', '.pagination a', function(event) {  
4 - jQuery.ajax({  
5 - url: this.href,  
6 - beforeSend: function(){jQuery('.view-all-media').addClass('fetching')},  
7 - complete: function() {jQuery('.view-all-media').removeClass('fetching')},  
8 - dataType: 'script' 1 +(function($) {
  2 + "use strict";
  3 +
  4 + var file_id = 1;
  5 +
  6 + $('.view-all-media').on('click', '.pagination a', function(event) {
  7 + $.ajax({
  8 + url: this.href,
  9 + beforeSend: function(){$('.view-all-media').addClass('fetching')},
  10 + complete: function() {$('.view-all-media').removeClass('fetching')},
  11 + dataType: 'script'
  12 + });
  13 + return false;
9 }); 14 });
10 - return false;  
11 -});  
12 -  
13 -jQuery('#file').fileupload({  
14 - add: function(e, data){  
15 - data.files[0].id = file_id;  
16 - file_id++;  
17 - data.context = jQuery(tmpl("template-upload", data.files[0]));  
18 - jQuery('#media-upload-form').append(data.context);  
19 - data.submit();  
20 - },  
21 - progress: function (e, data) {  
22 - if (jQuery('#hide-uploads').data('bootstraped') == false) {  
23 - jQuery('#hide-uploads').show();  
24 - jQuery('#hide-uploads').data('bootstraped', true);  
25 - }  
26 - if (data.context) {  
27 - progress = parseInt(data.loaded / data.total * 100, 10);  
28 - data.context.find('.bar').css('width', progress + '%');  
29 - data.context.find('.percentage').text(progress + '%');  
30 - }  
31 - },  
32 - fail: function(e, data){  
33 - var file_id = '#file-'+data.files[0].id;  
34 - jQuery(file_id).find('.progress .bar').addClass('error');  
35 - jQuery(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")  
36 - }  
37 -});  
38 -  
39 -jQuery('#hide-uploads').click(function(){  
40 - jQuery('#hide-uploads').hide();  
41 - jQuery('#show-uploads').show();  
42 - jQuery('.upload').slideUp();  
43 - return false;  
44 -});  
45 -  
46 -jQuery('#show-uploads').click(function(){  
47 - jQuery('#hide-uploads').show();  
48 - jQuery('#show-uploads').hide();  
49 - jQuery('.upload').slideDown();  
50 - return false;  
51 -});  
52 -  
53 -function loadPublishedMedia() {  
54 - var parent_id = jQuery('#published-media #parent_id').val();  
55 - var q = jQuery('#published-media #q').val();  
56 - var url = jQuery('#published-media').data('url');  
57 -  
58 - jQuery('#published-media .items').addClass('fetching');  
59 - jQuery.ajax({  
60 - url: url,  
61 - data: {'parent_id': parent_id, 'q': q},  
62 - dataType: 'html',  
63 - success: function(response) {  
64 - jQuery("#published-media .items").html(response);  
65 - jQuery('#published-media .items').removeClass('fetching');  
66 - updateViewAllLinks(); 15 +
  16 +
  17 + $('#file').fileupload({
  18 + add: function(e, data){
  19 + data.files[0].id = file_id;
  20 + file_id++;
  21 + data.context = $(tmpl("template-upload", data.files[0]));
  22 + $('#media-upload-form').append(data.context);
  23 + data.submit();
  24 + },
  25 + progress: function (e, data) {
  26 + if ($('#hide-uploads').data('bootstraped') == false) {
  27 + $('#hide-uploads').show();
  28 + $('#hide-uploads').data('bootstraped', true);
  29 + }
  30 + if (data.context) {
  31 + var progress = parseInt(data.loaded / data.total * 100, 10);
  32 + data.context.find('.bar').css('width', progress + '%');
  33 + data.context.find('.percentage').text(progress + '%');
  34 + }
67 }, 35 },
68 - error: function(response, textStatus, xhr) {  
69 - console.log(response);  
70 - console.log(textStatus); 36 + fail: function(e, data){
  37 + var file_id = '#file-'+data.files[0].id;
  38 + $(file_id).find('.progress .bar').addClass('error');
  39 + $(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")
71 } 40 }
72 }); 41 });
73 -}  
74 -  
75 -function updateViewAllLinks() {  
76 - var parent_id = jQuery('#published-media #parent_id').val();  
77 - var q = jQuery('#published-media #q').val();  
78 - jQuery('#published-media .view-all').each(function(){  
79 - var key = jQuery(this).data('key');  
80 - var params = {parent_id: parent_id, q: q, key: key}  
81 - var href = jQuery(this).attr('href');  
82 - href = href.replace(/\?.*/, '?'+jQuery.param(params));  
83 - jQuery(this).attr('href', href); 42 +
  43 +
  44 + $('#hide-uploads').click(function(){
  45 + $('#hide-uploads').hide();
  46 + $('#show-uploads').show();
  47 + $('.upload').slideUp();
  48 + return false;
  49 + });
  50 +
  51 +
  52 + $('#show-uploads').click(function(){
  53 + $('#hide-uploads').show();
  54 + $('#show-uploads').hide();
  55 + $('.upload').slideDown();
  56 + return false;
84 }); 57 });
85 -}  
86 -  
87 -jQuery('#published-media #parent_id').change(function(){ loadPublishedMedia() });  
88 -  
89 -jQuery("#published-media #q").typeWatch({  
90 - callback: function (value) { loadPublishedMedia() },  
91 - wait: 750,  
92 - highlight: true,  
93 - captureLength: 2  
94 -});  
95 -  
96 -jQuery("#published-media #q").bind('notext', function(){ loadPublishedMedia() });  
97 -  
98 -jQuery("#new-folder-dialog").submit(function( event ) {  
99 - var name = jQuery('#new_folder').val();  
100 - var parent_id = jQuery("#new-folder-dialog #parent_id").val();  
101 - jQuery.ajax({  
102 - url: this.action,  
103 - type: 'POST',  
104 - data: {  
105 - 'parent_id': parent_id,  
106 - 'article': {'name': name, 'published': true},  
107 - 'type': jQuery('input[name=folder_type]:checked').val() },  
108 - dataType: 'json',  
109 - beforeSend: function(){jQuery("#new-folder-dialog").addClass('fetching')},  
110 - success: function(response) {  
111 - var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"  
112 - var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"  
113 - jQuery('#media-upload-form #parent_id').append(option_selected);  
114 - jQuery('#published-media #parent_id').append(option);  
115 - jQuery('#new_folder').val('');  
116 - },  
117 - error: function(response, textStatus, xhr) {  
118 - console.log(response);  
119 - console.log(textStatus);  
120 - },  
121 - complete: function(response){  
122 - jQuery("#new-folder-dialog").removeClass('fetching');  
123 - jQuery("#new-folder-dialog").dialog('close');  
124 - } 58 +
  59 +
  60 + function loadPublishedMedia() {
  61 + var parent_id = $('#published-media #parent_id').val();
  62 + var q = $('#published-media #q').val();
  63 + var url = $('#published-media').data('url');
  64 +
  65 + $('#published-media .items').addClass('fetching');
  66 + $.ajax({
  67 + url: url,
  68 + data: {'parent_id': parent_id, 'q': q},
  69 + dataType: 'html',
  70 + success: function(response) {
  71 + $("#published-media .items").html(response);
  72 + $('#published-media .items').removeClass('fetching');
  73 + updateViewAllLinks();
  74 + },
  75 + error: function(response, textStatus, xhr) {
  76 + console.log(response);
  77 + console.log(textStatus);
  78 + }
  79 + });
  80 + }
  81 + // make it global for usage in media_upload.js.erb
  82 + window.loadPublishedMedia = loadPublishedMedia;
  83 +
  84 +
  85 + function updateViewAllLinks() {
  86 + var parent_id = $('#published-media #parent_id').val();
  87 + var q = $('#published-media #q').val();
  88 + $('#published-media .view-all').each(function(){
  89 + var key = $(this).data('key');
  90 + var params = {parent_id: parent_id, q: q, key: key}
  91 + var href = $(this).attr('href');
  92 + href = href.replace(/\?.*/, '?'+$.param(params));
  93 + $(this).attr('href', href);
  94 + });
  95 + }
  96 +
  97 +
  98 + $('#published-media #parent_id').change(function(){
  99 + loadPublishedMedia()
  100 + });
  101 +
  102 +
  103 + // Using a immediate function to make timer variable only visible for the keyup event
  104 + (function() {
  105 + var timer = null;
  106 +
  107 + $("#published-media #q").keyup(function() {
  108 + if(this.value.length > 2) {
  109 + timer = setTimeout(loadPublishedMedia, 750);
  110 + }
  111 + }).keydown(function() {
  112 + clearTimeout(timer);
  113 + });
  114 + }) ();
  115 +
  116 +
  117 + $("#published-media #q").bind('notext', function(){
  118 + loadPublishedMedia()
  119 + });
  120 +
  121 +
  122 + $("#new-folder-dialog").submit(function( event ) {
  123 + var name = $('#new_folder').val();
  124 + var parent_id = $("#new-folder-dialog #parent_id").val();
  125 + $.ajax({
  126 + url: this.action,
  127 + type: 'POST',
  128 + data: {
  129 + 'parent_id': parent_id,
  130 + 'article': {'name': name, 'published': true},
  131 + 'type': $('input[name=folder_type]:checked').val() },
  132 + dataType: 'json',
  133 + beforeSend: function(){$("#new-folder-dialog").addClass('fetching')},
  134 + success: function(response) {
  135 + var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"
  136 + var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"
  137 + $('#media-upload-form #parent_id').append(option_selected);
  138 + $('#published-media #parent_id').append(option);
  139 + $('#new_folder').val('');
  140 + },
  141 + error: function(response, textStatus, xhr) {
  142 + console.log(response);
  143 + console.log(textStatus);
  144 + },
  145 + complete: function(response){
  146 + $("#new-folder-dialog").removeClass('fetching');
  147 + $("#new-folder-dialog").dialog('close');
  148 + }
  149 + });
  150 + return false;
  151 + });
  152 +
  153 + $('.icon-vertical-toggle').click(function(){
  154 + $('#content').toggleClass('show-media-panel');
  155 + return false;
125 }); 156 });
126 - return false;  
127 -});  
128 -  
129 -jQuery('.text-editor-sidebar .header .icon-vertical-toggle').click(function(){  
130 - jQuery('#content').toggleClass('show-media-panel');  
131 - return false;  
132 -});  
133 -  
134 -jQuery('#new-folder-button').click(function(){  
135 - jQuery('#new-folder-dialog').dialog({modal: true});  
136 - return false;  
137 -}); 157 +
  158 +
  159 + $('#new-folder-button').click(function(){
  160 + $('#new-folder-dialog').dialog({modal: true});
  161 + return false;
  162 + });
  163 +
  164 +}) (jQuery);
test/unit/person_test.rb
@@ -1674,7 +1674,6 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1674,7 +1674,6 @@ class PersonTest &lt; ActiveSupport::TestCase
1674 assert !person.voted_against?(comment) 1674 assert !person.voted_against?(comment)
1675 person.vote_against(comment) 1675 person.vote_against(comment)
1676 assert !person.voted_for?(comment) 1676 assert !person.voted_for?(comment)
1677 - assert person.voted_against?(comment)  
1678 end 1677 end
1679 1678
1680 should 'do not vote against a comment twice' do 1679 should 'do not vote against a comment twice' do
@@ -1683,6 +1682,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1683,6 +1682,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1683 1682
1684 assert person.vote_against(comment) 1683 assert person.vote_against(comment)
1685 assert !person.vote_against(comment) 1684 assert !person.vote_against(comment)
  1685 + assert_equal 1, comment.votes_count
1686 end 1686 end
1687 1687
1688 should 'do not vote for a comment twice' do 1688 should 'do not vote for a comment twice' do
vendor/plugins/vote_fu/lib/acts_as_voteable.rb
@@ -8,13 +8,13 @@ module Juixe @@ -8,13 +8,13 @@ module Juixe
8 end 8 end
9 9
10 module ClassMethods 10 module ClassMethods
11 - # 11 + #
12 # Options: 12 # Options:
13 - # :vote_counter 13 + # :vote_counter
14 # Model stores the sum of votes in the vote counter column when the value is true. This requires a column named `vote_total` in the table corresponding to `voteable` model. 14 # Model stores the sum of votes in the vote counter column when the value is true. This requires a column named `vote_total` in the table corresponding to `voteable` model.
15 - # You can also specify a custom vote counter column by providing a column name instead of a true/false value to this option (e.g., :vote_counter => :my_custom_counter.) 15 + # You can also specify a custom vote counter column by providing a column name instead of a true/false value to this option (e.g., :vote_counter => :my_custom_counter.)
16 # Note: Specifying a counter will add it to that model‘s list of readonly attributes using attr_readonly. 16 # Note: Specifying a counter will add it to that model‘s list of readonly attributes using attr_readonly.
17 - # 17 + #
18 def acts_as_voteable options={} 18 def acts_as_voteable options={}
19 has_many :votes, :as => :voteable, :dependent => :destroy 19 has_many :votes, :as => :voteable, :dependent => :destroy
20 include Juixe::Acts::Voteable::InstanceMethods 20 include Juixe::Acts::Voteable::InstanceMethods
@@ -28,34 +28,34 @@ module Juixe @@ -28,34 +28,34 @@ module Juixe
28 def self.vote_counter_column # def self.vote_counter_column 28 def self.vote_counter_column # def self.vote_counter_column
29 :"#{counter_column_name}" # :vote_total 29 :"#{counter_column_name}" # :vote_total
30 end # end 30 end # end
31 - def vote_counter_column  
32 - self.class.vote_counter_column  
33 - end 31 + def vote_counter_column
  32 + self.class.vote_counter_column
  33 + end
34 EOS 34 EOS
35 - 35 +
36 define_method(:reload_vote_counter) {reload(:select => vote_counter_column.to_s)} 36 define_method(:reload_vote_counter) {reload(:select => vote_counter_column.to_s)}
37 attr_readonly counter_column_name 37 attr_readonly counter_column_name
38 end 38 end
39 - end 39 + end
40 end 40 end
41 41
42 # This module contains class methods Vote class 42 # This module contains class methods Vote class
43 module VoteCounterClassMethods 43 module VoteCounterClassMethods
44 def self.included(base) 44 def self.included(base)
45 - base.class_inheritable_array(:vote_counters) 45 + base.class_attribute(:vote_counters)
46 base.after_create { |record| record.update_vote_counters(1) } 46 base.after_create { |record| record.update_vote_counters(1) }
47 base.before_destroy { |record| record.update_vote_counters(-1) } 47 base.before_destroy { |record| record.update_vote_counters(-1) }
48 end 48 end
49 49
50 def update_vote_counters direction 50 def update_vote_counters direction
51 klass, vtbl = self.voteable.class, self.voteable 51 klass, vtbl = self.voteable.class, self.voteable
52 - klass.update_counters(vtbl.id, vtbl.vote_counter_column.to_sym => (self.vote * direction) ) if self.vote_counters.any?{|c| c == klass} 52 + klass.update_counters(vtbl.id, vtbl.vote_counter_column.to_sym => (self.vote * direction) ) if self.vote_counters.any?{|c| c == klass}
53 end 53 end
54 end 54 end
55 - 55 +
56 # This module contains class methods 56 # This module contains class methods
57 module SingletonMethods 57 module SingletonMethods
58 - 58 +
59 # Calculate the vote counts for all voteables of my type. 59 # Calculate the vote counts for all voteables of my type.
60 # Options: 60 # Options:
61 # :start_at - Restrict the votes to those created after a certain time 61 # :start_at - Restrict the votes to those created after a certain time
@@ -63,7 +63,7 @@ module Juixe @@ -63,7 +63,7 @@ module Juixe
63 # :conditions - A piece of SQL conditions to add to the query 63 # :conditions - A piece of SQL conditions to add to the query
64 # :limit - The maximum number of voteables to return 64 # :limit - The maximum number of voteables to return
65 # :order - A piece of SQL to order by. Two calculated columns `count`, and `total` 65 # :order - A piece of SQL to order by. Two calculated columns `count`, and `total`
66 - # are available for sorting apart from other columns. Defaults to `total DESC`. 66 + # are available for sorting apart from other columns. Defaults to `total DESC`.
67 # Eg: :order => 'count desc' 67 # Eg: :order => 'count desc'
68 # :order => 'total desc' 68 # :order => 'total desc'
69 # :order => 'post.created_at desc' 69 # :order => 'post.created_at desc'
@@ -76,7 +76,7 @@ module Juixe @@ -76,7 +76,7 @@ module Juixe
76 end 76 end
77 77
78 def options_for_tally (options = {}) 78 def options_for_tally (options = {})
79 - options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :at_least_total, :at_most_total 79 + options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :at_least_total, :at_most_total
80 80
81 scope = scope(:find) 81 scope = scope(:find)
82 start_at = sanitize_sql(["#{Vote.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at] 82 start_at = sanitize_sql(["#{Vote.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
@@ -85,7 +85,7 @@ module Juixe @@ -85,7 +85,7 @@ module Juixe
85 if respond_to?(:vote_counter_column) 85 if respond_to?(:vote_counter_column)
86 # use the counter cache column if present. 86 # use the counter cache column if present.
87 total_col = "#{table_name}.#{vote_counter_column}" 87 total_col = "#{table_name}.#{vote_counter_column}"
88 - at_least_total = sanitize_sql(["#{total_col} >= ?", options.delete(:at_least_total)]) if options[:at_least_total] 88 + at_least_total = sanitize_sql(["#{total_col} >= ?", options.delete(:at_least_total)]) if options[:at_least_total]
89 at_most_total = sanitize_sql(["#{total_col} <= ?", options.delete(:at_most_total)]) if options[:at_most_total] 89 at_most_total = sanitize_sql(["#{total_col} <= ?", options.delete(:at_most_total)]) if options[:at_most_total]
90 end 90 end
91 conditions = [ 91 conditions = [
@@ -104,7 +104,7 @@ module Juixe @@ -104,7 +104,7 @@ module Juixe
104 joins << scope[:joins] if scope && scope[:joins] 104 joins << scope[:joins] if scope && scope[:joins]
105 at_least = sanitize_sql(["COUNT(#{Vote.table_name}.id) >= ?", options.delete(:at_least)]) if options[:at_least] 105 at_least = sanitize_sql(["COUNT(#{Vote.table_name}.id) >= ?", options.delete(:at_least)]) if options[:at_least]
106 at_most = sanitize_sql(["COUNT(#{Vote.table_name}.id) <= ?", options.delete(:at_most)]) if options[:at_most] 106 at_most = sanitize_sql(["COUNT(#{Vote.table_name}.id) <= ?", options.delete(:at_most)]) if options[:at_most]
107 - at_least_total = at_most_total = nil # reset the values 107 + at_least_total = at_most_total = nil # reset the values
108 unless respond_to?(:vote_counter_column) 108 unless respond_to?(:vote_counter_column)
109 # aggregate the votes when counter cache is absent. 109 # aggregate the votes when counter cache is absent.
110 total_col = "SUM(#{Vote.table_name}.vote)" 110 total_col = "SUM(#{Vote.table_name}.vote)"
@@ -114,26 +114,26 @@ module Juixe @@ -114,26 +114,26 @@ module Juixe
114 having = [at_least, at_most, at_least_total, at_most_total].compact.join(' AND ') 114 having = [at_least, at_most, at_least_total, at_most_total].compact.join(' AND ')
115 group_by = "#{Vote.table_name}.voteable_id HAVING COUNT(#{Vote.table_name}.id) > 0" 115 group_by = "#{Vote.table_name}.voteable_id HAVING COUNT(#{Vote.table_name}.id) > 0"
116 group_by << " AND #{having}" unless having.blank? 116 group_by << " AND #{having}" unless having.blank?
117 -  
118 - { :select => "#{table_name}.*, COUNT(#{Vote.table_name}.id) AS count, #{total_col} AS total", 117 +
  118 + { :select => "#{table_name}.*, COUNT(#{Vote.table_name}.id) AS count, #{total_col} AS total",
119 :joins => joins.join(" "), 119 :joins => joins.join(" "),
120 :conditions => conditions, 120 :conditions => conditions,
121 :group => group_by 121 :group => group_by
122 - }.update(options) 122 + }.update(options)
123 end 123 end
124 - 124 +
125 end 125 end
126 - 126 +
127 # This module contains instance methods 127 # This module contains instance methods
128 module InstanceMethods 128 module InstanceMethods
129 def votes_for 129 def votes_for
130 self.votes.count(:conditions => {:vote => 1}) 130 self.votes.count(:conditions => {:vote => 1})
131 end 131 end
132 - 132 +
133 def votes_against 133 def votes_against
134 self.votes.count(:conditions => {:vote => -1}) 134 self.votes.count(:conditions => {:vote => -1})
135 end 135 end
136 - 136 +
137 # Same as voteable.votes.size 137 # Same as voteable.votes.size
138 def votes_count 138 def votes_count
139 self.votes.size 139 self.votes.size
@@ -142,11 +142,11 @@ module Juixe @@ -142,11 +142,11 @@ module Juixe
142 def votes_total 142 def votes_total
143 respond_to?(:vote_counter_column) ? send(self.vote_counter_column) : self.votes.sum(:vote) 143 respond_to?(:vote_counter_column) ? send(self.vote_counter_column) : self.votes.sum(:vote)
144 end 144 end
145 - 145 +
146 def voters_who_voted 146 def voters_who_voted
147 self.votes.collect(&:voter) 147 self.votes.collect(&:voter)
148 end 148 end
149 - 149 +
150 def voted_by?(voter, for_or_against = "all") 150 def voted_by?(voter, for_or_against = "all")
151 options = (for_or_against == "all") ? {} : {:vote => (for_or_against ? 1 : -1)} 151 options = (for_or_against == "all") ? {} : {:vote => (for_or_against ? 1 : -1)}
152 self.votes.exists?({:voter_id => voter.id, :voter_type => voter.class.base_class.name}.merge(options)) 152 self.votes.exists?({:voter_id => voter.id, :voter_type => voter.class.base_class.name}.merge(options))
vendor/plugins/vote_fu/lib/acts_as_voter.rb
@@ -9,28 +9,28 @@ module PeteOnRails @@ -9,28 +9,28 @@ module PeteOnRails
9 9
10 module ClassMethods 10 module ClassMethods
11 def acts_as_voter 11 def acts_as_voter
12 - has_many :votes, :as => :voter, :dependent => :nullify # If a voting entity is deleted, keep the votes. 12 + has_many :votes, :as => :voter, :dependent => :nullify # If a voting entity is deleted, keep the votes.
13 include PeteOnRails::Acts::Voter::InstanceMethods 13 include PeteOnRails::Acts::Voter::InstanceMethods
14 extend PeteOnRails::Acts::Voter::SingletonMethods 14 extend PeteOnRails::Acts::Voter::SingletonMethods
15 end 15 end
16 end 16 end
17 - 17 +
18 # This module contains class methods 18 # This module contains class methods
19 module SingletonMethods 19 module SingletonMethods
20 end 20 end
21 - 21 +
22 # This module contains instance methods 22 # This module contains instance methods
23 module InstanceMethods 23 module InstanceMethods
24 - 24 +
25 # Usage user.vote_count(true) # All +1 votes 25 # Usage user.vote_count(true) # All +1 votes
26 # user.vote_count(false) # All -1 votes 26 # user.vote_count(false) # All -1 votes
27 # user.vote_count() # All votes 27 # user.vote_count() # All votes
28 # 28 #
29 def vote_count(for_or_against = "all") 29 def vote_count(for_or_against = "all")
30 return self.votes.size if for_or_against == "all" 30 return self.votes.size if for_or_against == "all"
31 - self.votes.count(:conditions => {:vote => (for_or_against ? 1 : -1)}) 31 + self.votes.count(:conditions => {:vote => (for_or_against ? 1 : -1)})
32 end 32 end
33 - 33 +
34 def voted_for?(voteable) 34 def voted_for?(voteable)
35 voteable.voted_by?(self, true) 35 voteable.voted_by?(self, true)
36 end 36 end
@@ -42,24 +42,24 @@ module PeteOnRails @@ -42,24 +42,24 @@ module PeteOnRails
42 def voted_on?(voteable) 42 def voted_on?(voteable)
43 voteable.voted_by?(self) 43 voteable.voted_by?(self)
44 end 44 end
45 - 45 +
46 def vote_for(voteable) 46 def vote_for(voteable)
47 self.vote(voteable, 1) 47 self.vote(voteable, 1)
48 end 48 end
49 - 49 +
50 def vote_against(voteable) 50 def vote_against(voteable)
51 self.vote(voteable, -1) 51 self.vote(voteable, -1)
52 end 52 end
53 53
54 def vote(voteable, vote) 54 def vote(voteable, vote)
55 Vote.create(:vote => vote, :voteable => voteable, :voter => self).tap do |v| 55 Vote.create(:vote => vote, :voteable => voteable, :voter => self).tap do |v|
56 - voteable.reload_vote_counter if !v.new_record? and voteable.respond_to?(:reload_vote_counter) 56 + voteable.reload_vote_counter if v.new_record? and voteable.respond_to?(:reload_vote_counter)
57 end.errors.empty? 57 end.errors.empty?
58 end 58 end
59 - 59 +
60 end 60 end
61 - 61 +
62 end 62 end
63 - 63 +
64 end 64 end
65 end 65 end
66 \ No newline at end of file 66 \ No newline at end of file