OSDN Git Service

b47fbdaef1da52337e6bd4707bb960d006d49795
[pettanr/pettanr.git] / lib / manifest / list.rb
1
2 module Pettanr
3   class ListManager
4     class BaseList
5       def initialize page, page_size, operators, item_name, list_name, conf, manifest
6         @operators = operators
7         @item_name = item_name
8         @list_name = list_name
9         @conf = conf
10         @manifest = manifest
11         @default_page_size = @conf['default_page_size'] || 25
12         @max_page_size = @conf['max_page_size'] || 100
13         @page = self.page_number(page) 
14         @page_size = self.page_size page_size
15         
16         @model = @item_name.classify.constantize
17         @offset = (@page -1) * @page_size
18         @table_name = @model.table_name
19        if @model.content?
20           @owner_model = @model.owner_model
21           @owner_table_name = @owner_model.table_name if @owner_model
22         end
23       end
24       
25       def page_number prm = nil
26         page = prm.to_i
27         page = 1 if page < 1
28         page
29       end
30       
31       def page_size prm
32         page_size = prm.to_i
33         page_size = @max_page_size if page_size > @max_page_size
34         page_size = @default_page_size if page_size < 1
35         page_size
36       end
37       
38       def where
39         @model.list_where
40       end
41       
42       def includes
43         @owner_model ? {@owner_model.item_name => {}} : {}
44       end
45       
46       def order
47         @model.list_order
48       end
49       
50       def items
51         @model.where(self.where()).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
52       end
53       
54       def paginate
55         c = @model.where(self.where()).includes(self.includes).count
56         Kaminari.paginate_array(Array.new(c, nil)).page(@offset).per(@page_size)
57       end
58       
59     end
60     
61     class PublicList < BaseList
62     end
63     
64     class PrivateList < BaseList
65       def where 
66         case @model.owner_type
67         when :author
68           operator = @operators.author
69         when :artist
70           operator = @operators.artist
71         end
72         t = @owner_model ? @owner_table_name : @table_name
73         [t + '.' + @model.owner_type.to_s + '_id = ?', operator.id]
74       end
75      
76     end
77     
78     class HasManyList < BaseList
79       def initialize page, page_size, operators, item_name, list_name, conf, manifest
80         super
81         @association_name = @conf['association_name']
82         @has_many_conf = @manifest.model(@item_name).associations['has_many'] || {}
83         @association_conf = @has_many_conf[@association_name] || {}
84         @association_model_name = @association_conf['model']
85         @association_model = @association_model_name.classify.constantize
86         @foreign_key = @association_conf['foreign_key']
87       end
88       
89       def where parent_item
90         w = @model.list_where
91         w += ' and ' unless w.blank?
92         t = @owner_model ? @owner_table_name : @table_name
93         [w + @association_model_name + '.' + @foreign_key + ' = ?', parent_item.id] 
94       end
95       
96       def includes
97   #   @with_model_name ? {@with_model_name.classify.constantize.table_name => {}} : {}
98         w = @owner_model ? {@owner_model.item_name => {}} : {}
99         w.merge({@association_model.table_name => {} }) 
100       end
101       
102       def items parent_item
103         @model.where(self.where(parent_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
104       end
105       
106       def paginate parent_item
107         Kaminari.paginate_array(Array.new(@model.where(self.where(parent_item).includes(self.includes)).count, nil)).page(@offset).per(@page_size)
108       end
109       
110     end
111     
112     class FilterList < BaseList
113       def initialize page, page_size, operators, item_name, list_name, conf, manifest
114         super
115         @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
116         @from = @list_list_conf['from']
117         @filter_key = @list_list_conf['filter_key']
118         @includes = @list_list_conf['includes']
119         
120         @with_model_name = @list_list_conf['with']
121       end
122       
123       def where filter_item
124         w = @model.list_where
125         w += ' and ' unless w.blank?
126         [w + @table_name + '.' + @filter_key + ' = ?', filter_item.id] 
127       end
128       
129       def includes
130         return @includes if @includes
131         w = @owner_model ? {@owner_model.item_name => {}} : {}
132         w.merge({@from => {} }) 
133       end
134       
135       def items filter_item
136         @model.where(self.where(filter_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
137       end
138       
139       def paginate filter_item
140         Kaminari.paginate_array(Array.new(@model.where(self.where(filter_item).includes(self.includes)).count, nil)).page(@offset).per(@page_size)
141       end
142       
143     end
144     
145     class ThroughFilterList < FilterList
146       def initialize page, page_size, operators, item_name, list_name, conf, manifest
147         super
148         @through = @list_list_conf['through']
149       end
150       
151       def includes
152         {@through => {@from => {}} }
153       end
154       
155       def where filter_item
156         w = @model.list_where
157         w += ' and ' unless w.blank?
158         [w + @through + '.' + @filter_key + ' = ?', filter_item.id] 
159       end
160       
161     end
162     
163     class ElementFilterList < FilterList
164       def includes
165         {@owner_model.item_name => {}}
166       end
167       
168       def where filter_item
169         w = @model.list_where
170         w += ' and ' unless w.blank?
171         [w + @owner_table_name + '.' + @filter_key + ' = ?', filter_item.id] 
172       end
173       
174     end
175     
176     @@types = {
177       'public' => PublicList, 'private' => PrivateList, 
178       'has_many' => HasManyList, 'filter' => FilterList, 
179       'through_filter' => ThroughFilterList, 'element_filter' => ElementFilterList
180     }
181     def initialize list_manifest
182       @list_manifest = list_manifest
183       @item_name = @list_manifest.item_name
184       @manifest = @list_manifest.manifest
185       @list_conf = @list_manifest.conf
186       @lists = {}
187       @list_manifest.lists.each {|list_name, conf|
188         type = conf['type']
189         @lists[list_name] = @@types[type]
190       }
191     end
192     
193     def open list_name, page, page_size, operators
194       raise "undefined list for #{@item_name}::#{list_name}\nconf:#{@list_conf}\n" unless @lists[list_name]
195       @lists[list_name].new page, page_size, operators, @item_name, list_name, @list_conf, @manifest
196     end
197     
198   end
199 end
200