c1087999a0dfa5645a6dc6f1ce2fd0c2200a8f07
[redakcja.git] / redmine / redmine_publications / lib / redmine_publications / issue_patch.rb
1 module RedminePublications
2   # Patches Redmine's Issues dynamically. Adds a +after_save+ filter.
3
4   module IssuePatch
5     def self.included(base) # :nodoc:
6       base.extend(ClassMethods)
7  
8       base.send(:include, InstanceMethods)
9  
10       # Same as typing in the class
11       base.class_eval do
12         unloadable # Send unloadable so it will not be unloaded in development
13  
14         validate :check_relations
15         after_save :update_relations
16       end
17  
18     end
19     
20     module ClassMethods
21     end
22     
23     module InstanceMethods
24
25       def publication_names     
26         if not @pubnames
27           self.publications.map { |pub| pub.name }
28         else
29           @pubnames        
30         end
31       end
32
33       def publication_names=(value)
34         @pubnames = value.sort!
35       end
36
37       def publications
38         Publication.all( 
39           :joins => 
40             "JOIN issue_publications ON (issue_publications.publication_id = publications.id)",
41           :conditions =>
42             ["issue_publications.issue_id = ? ", self.id] )     
43       end
44
45       def check_relations
46         current_names = self.publication_names
47         non_existant = []
48
49         pubs =  Publication.find_all_by_name(current_names).map {|i| i.name}
50         missing = current_names.select {|name| not pubs.include?name }
51
52         if not missing.empty?
53           errors.add("publications", "Missing publication(s): " + missing.join(', '))
54         end
55      end
56
57      def update_relations
58         old = self.publications
59         current_names = self.publication_names
60         Rails.logger.info('[INFO] Updating relations: old= ' << old.inspect << ' current=' << current_names.inspect)
61
62         # delete unused relations
63         deleted = old.select { |v| not (current_names.include?(v.name)) }
64         deleted.each do |pub| 
65           IssuePublication.delete_all(["issue_publications.issue_id = ? AND issue_publications.publication_id = ?", self.id, pub.id])
66         end
67
68         current_names.each do |name|    
69             pub = Publication.find_by_name(name)
70             IssuePublication.find_or_create_by_publication_id_and_issue_id(pub.id, self.id)
71         end
72
73         return true
74      end
75
76     end
77   end
78 end