OSDN Git Service

test speech balloon extended
[pettanr/pettanr.git] / app / models / story.rb
1 #ストーリー
2 class Story < Peta::Binder
3   load_manifest
4   has_many :story_sheets
5   belongs_to :comic
6   
7   validates :comic_id, :presence => true, :numericality => true, :existence => {:both => false}
8   validates :title, :presence => true, :length => {:maximum => 100}
9   validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1}
10   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
11   
12   def supply_default
13     self.comic_id = nil
14     self.visible = 0 if self.visible.blank?
15     self.t = nil
16   end
17   
18   def overwrite
19   end
20   
21   def visible? operators
22     return false unless super
23     self.visible > 0
24   end
25   
26   def disp_t
27     self.t + 1
28   end
29   
30   def disp_t_by_text
31     I18n.t('stories.show.t', :t => self.disp_t)
32   end
33   
34   def title_with_t
35     self.disp_t_by_text  + ':' + self.title
36   end
37   
38   def story_sheets_count
39     StorySheet.where(['story_sheets.story_id = ?', self.id]).count
40   end
41   
42   def self.public_list_where
43     'stories.visible > 0'
44   end
45   
46   def self.list_order
47     'stories.updated_at desc'
48   end
49   
50   def self.list_opt
51     {:comic => {:author => {}} }
52   end
53   
54   def self.by_author_list_includes
55     {
56       :comic => {
57         :author => {}
58       }
59     }
60   end
61   
62   def self.list_json_opt
63     {:include => {:comic => {:include => {:author => {}}} }}
64   end
65   
66   def self.show_opt
67     {:include => {:comic => {:author => {}} }}
68   end
69   
70   def self.show_json_opt
71     {:include => {:comic => {:include => {:author => {}}} }}
72   end
73   
74   def self.visible_count
75     Story.count 'visible > 0'
76   end
77   
78   def destroy_with_story_sheet
79     res = false
80     Story.transaction do
81       self.story_sheets.each do |story_sheet|
82         raise ActiveRecord::Rollback unless story_sheet.destroy
83       end
84       raise ActiveRecord::Rollback unless self.destroy
85       res = true
86     end
87     res
88   end
89   
90   def self.new_t comic_id
91     r = Story.max_t(comic_id)
92     r.blank? ? 0 : r.to_i + 1
93   end
94   
95   def self.max_t comic_id
96     Story.maximum(:t, :conditions => ['comic_id = ?', comic_id])
97   end
98   
99   def self.find_t comic_id, t
100     Story.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
101   end
102   
103   def self.collect_t story
104     r = Story.find(:all, :conditions => ['comic_id = ?', story.comic_id], :order => 't')
105     r.map {|s| s.t}
106   end
107   
108   def self.serial? ary
109     i = 0
110     ary.compact.sort.each do |t|
111       break false unless t == i
112       i += 1
113     end
114     ary.compact.size == i
115   end
116   
117   def self.validate_t story
118     Story.serial?(Story.collect_t(story))
119   end
120   
121   def insert_shift
122     Story.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
123   end
124   
125   def lesser_shift old_t
126     self.t = 0 if self.t < 0
127     Story.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, self.t, old_t])
128   end
129   
130   def higher_shift old_t
131     nf = Story.find_t(self.comic_id, self.t)
132     max_t = Story.max_t(self.comic_id).to_i
133     self.t = max_t if self.t > max_t
134     Story.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, old_t, self.t])
135   end
136   
137   def update_shift old_t
138     if self.t > old_t
139       higher_shift old_t
140     else
141       lesser_shift old_t
142     end
143   end
144   
145   def rotate old_t = nil
146     if self.new_record?
147       if self.t.blank?
148         self.t = Story.new_t self.comic_id
149       else
150         self.insert_shift
151       end
152     else
153       if self.t.blank?
154       else
155         self.update_shift old_t
156       end
157     end
158   end
159   
160   def allow? operators
161     return nil if self.comic_id == nil
162     self.comic.own?(operators)
163   end
164   
165   def store operators, old_t = nil
166     res = false
167     Story.transaction do
168       case self.allow? operators
169       when true
170         self.rotate old_t
171       when false
172         raise ActiveRecord::Forbidden
173       else
174       end
175       res = self.save
176       raise ActiveRecord::Rollback unless res
177       res = Story.validate_t(self) 
178       unless res
179         self.errors.add :t, 'unserialized'
180         raise ActiveRecord::Rollback 
181       end
182     end
183     res
184   end
185   
186   def destroy_and_shorten
187     res = false
188     Story.transaction do
189       Story.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t])
190       raise ActiveRecord::Rollback unless self.destroy_with_story_sheet
191       res = true
192     end
193     res
194   end
195   
196   
197 end