module Pettanr
- class ListManager
- class BaseList
- def initialize page, page_size, operators, item_name, list_name, conf, manifest
- @operators = operators
- @item_name = item_name
- @list_name = list_name
- @conf = conf
- @manifest = manifest
- @default_page_size = @conf['default_page_size'] || 25
- @max_page_size = @conf['max_page_size'] || 100
- @page = self.page_number(page)
- @page_size = self.page_size page_size
-
- @model = @item_name.classify.constantize
- @offset = (@page -1) * @page_size
- @table_name = @model.table_name
- if @model.content?
- @owner_model = @model.owner_model
- @owner_table_name = @owner_model.table_name if @owner_model
+ module Manifest
+ class List
+ def self.set_default my_manifest
+ my_manifest.each {|item_name, list_manifest|
+ raise "undefined type for lists > #{item_name} > #{list_name}\n" unless list_manifest['type']
+ list_manifest['options'] ||= {}
+ list_manifest|['options'].each {|option_name, option_manifest|
+ option_manifest['default_page_size'] ||= 25
+ option_manifest['max_page_size'] ||= 100
+ }
+ @@types[list_manifest['type']].set_default list_manifest['options']
+ # 'required' 'number'
+ }
+ end
+
+ class BaseList
+ def initialize page, page_size, operators, item_name, list_name, conf, manifest
+ @operators = operators
+ @item_name = item_name
+ @list_name = list_name
+ @conf = conf
+ @manifest = manifest
+ @default_page_size = @conf['default_page_size'] || 25
+ @max_page_size = @conf['max_page_size'] || 100
+ @page = self.page_number(page)
+ @page_size = self.page_size page_size
+
+ @model = @item_name.classify.constantize
+ @offset = (@page -1) * @page_size
+ @table_name = @model.table_name
+ if @model.content?
+ @owner_model = @model.owner_model
+ @owner_table_name = @owner_model.table_name if @owner_model
+ end
end
- end
-
- def page_number prm = nil
- page = prm.to_i
- page = 1 if page < 1
- page
- end
-
- def page_size prm
- page_size = prm.to_i
- page_size = @max_page_size if page_size > @max_page_size
- page_size = @default_page_size if page_size < 1
- page_size
- end
-
- def where
- @model.list_where
- end
-
- def includes
- if @owner_model
- if @owner_model.owner_model
- {@owner_model.item_name => {@owner_model.owner_model.item_name => {}}}
+
+ def page_number prm = nil
+ page = prm.to_i
+ page = 1 if page < 1
+ page
+ end
+
+ def page_size prm
+ page_size = prm.to_i
+ page_size = @max_page_size if page_size > @max_page_size
+ page_size = @default_page_size if page_size < 1
+ page_size
+ end
+
+ def where
+ @model.list_where
+ end
+
+ def includes
+ if @owner_model
+ if @owner_model.owner_model
+ {@owner_model.item_name => {@owner_model.owner_model.item_name => {}}}
+ else
+ {@owner_model.item_name => {}}
+ end
else
- {@owner_model.item_name => {}}
+ {}
end
- else
- {}
+ end
+
+ def order
+ @model.list_order
+ end
+
+ def items
+ @model.where(self.where()).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
+ end
+
+ def paginate
+ c = @model.where(self.where()).includes(self.includes).count
+ Kaminari.paginate_array(Array.new(c, nil)).page(@offset).per(@page_size)
+ end
+
+ def self.add_action item_name, action_name, list_name, list_conf
+ return
end
end
- def order
- @model.list_order
- end
-
- def items
- @model.where(self.where()).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
- end
-
- def paginate
- c = @model.where(self.where()).includes(self.includes).count
- Kaminari.paginate_array(Array.new(c, nil)).page(@offset).per(@page_size)
- end
-
- def self.add_action item_name, action_name, list_name, list_conf
- return
+ class PublicList < BaseList
+
+ def self.set_default option_manifest
+ end
+
+ def self._add_action item_name, action_name, list_name, list_conf
+ model = item_name.classify.constantize
+ controller_name = model.plural + 'Controller'
+ controller = controller_name.constantize
+ return if controller.method_defined?(action_name)
+ controller.define_method(action_name) do
+ public_list
+ end
+ end
end
- end
-
- class PublicList < BaseList
- def self._add_action item_name, action_name, list_name, list_conf
- model = item_name.classify.constantize
- controller_name = model.plural + 'Controller'
- controller = controller_name.constantize
- return if controller.method_defined?(action_name)
- controller.define_method(action_name) do
- public_list
+ class PrivateList < BaseList
+ def self.set_default option_manifest
end
- end
- end
-
- class PrivateList < BaseList
- def where
- case @model.owner_type
- when :author
- operator = @operators.author
- when :artist
- operator = @operators.artist
- end
- t = if @owner_model
- if @owner_model.owner_model
- @owner_model.owner_model.table_name
+
+ def where
+ case @model.owner_type
+ when :author
+ operator = @operators.author
+ when :artist
+ operator = @operators.artist
+ end
+ t = if @owner_model
+ if @owner_model.owner_model
+ @owner_model.owner_model.table_name
+ else
+ @owner_model.table_name
+ end
else
- @owner_model.table_name
+ @table_name
end
- else
- @table_name
+ [t + '.' + @model.owner_type.to_s + '_id = ?', operator.id]
end
- [t + '.' + @model.owner_type.to_s + '_id = ?', operator.id]
- end
- end
-
- class SystemResourceList < BaseList
- def items
- @model.enable_list
end
- end
-
- class HasManyList < BaseList
- attr :association_model_name
- def initialize page, page_size, operators, item_name, list_name, conf, manifest
- super
- @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
- @association_name = @list_list_conf['association_name']
- @has_many_conf = @manifest.model(@item_name).associations['has_many'] || {}
- @association_conf = @has_many_conf[@association_name] || {}
- @association_model_name = @association_conf['model']
- @association_model = @association_model_name.classify.constantize
- @foreign_key = @association_conf['foreign_key']
- if @association_model.content?
- @owner_model = @association_model.owner_model
- @owner_table_name = @owner_model.table_name if @owner_model
+ class SystemResourceList < BaseList
+ def items
+ @model.enable_list
end
+
end
- def where parent_item
- w = @association_model.list_where
- w += ' and ' unless w.blank?
- [w + @association_model.table_name + '.' + @foreign_key + ' = ?', parent_item.id]
- end
-
- def includes
- # @with_model_name ? {@with_model_name.classify.constantize.table_name => {}} : {}
- w = @owner_model ? {@owner_model.item_name => {}} : {}
- w.merge({})
- end
-
- def items parent_item
- @association_model.where(self.where(parent_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
- end
-
- def paginate parent_item
- Kaminari.paginate_array(Array.new(@association_model.where(self.where(parent_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
- end
-
- def self._add_action item_name, action_name, list_name, list_conf
- model = item_name.classify.constantize
- controller_name = model.plural + 'Controller'
- controller = controller_name.constantize
- association_name = list_conf['association_name']
- has_many_conf = Pettanr::Application::manifest.model(item_name).associations['has_many'] || {}
- association_conf = has_many_conf[association_name] || {}
- association_model_name = association_conf['model']
- return if controller.method_defined?(action_name)
- controller.define_method(action_name) do
- has_many_list item_name, list_name, association_model_name, params
+ class HasManyList < BaseList
+ attr :association_model_name
+ def initialize page, page_size, operators, item_name, list_name, conf, manifest
+ super
+ @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
+ @association_name = @list_list_conf['association_name']
+ @has_many_conf = @manifest.model(@item_name).associations['has_many'] || {}
+ @association_conf = @has_many_conf[@association_name] || {}
+ @association_model_name = @association_conf['model']
+ @association_model = @association_model_name.classify.constantize
+ @foreign_key = @association_conf['foreign_key']
+ if @association_model.content?
+ @owner_model = @association_model.owner_model
+ @owner_table_name = @owner_model.table_name if @owner_model
+ end
end
- end
-
- end
-
- class HasManyThroughList < BaseList
- attr :association_model_name
- def initialize page, page_size, operators, item_name, list_name, conf, manifest
- super
- @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
- @association_name = @list_list_conf['association_name']
- @has_many_conf = @manifest.model(@item_name).associations['has_many'] || {}
- @association_conf = @has_many_conf[@association_name] || {}
- @association_through_model_name = @association_conf['through']
- @association_through_model = @association_through_model_name.classify.constantize
- @association_model_name = @association_conf['model']
- @association_model = @association_model_name.classify.constantize
- @foreign_key = @association_conf['foreign_key']
- if @association_model.content?
- @owner_model = @association_model.owner_model
- @owner_table_name = @owner_model.table_name if @owner_model
+
+ def self.set_default option_manifest
+ option_manifest['association_name'] ||= 100
end
- end
-
- def where root_item
- w = @association_model.list_where
- w += ' and ' unless w.blank?
- [w + @association_through_model.table_name + '.' + @foreign_key + ' = ?', root_item.id]
- end
-
- def includes
- {@association_through_model.table_name => {@item_name => {}}}
- end
-
- def items root_item
- @association_model.where(self.where(root_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
- end
-
- def paginate root_item
- Kaminari.paginate_array(Array.new(@association_model.where(self.where(root_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
- end
-
- end
-
- class FilterList < BaseList
- attr :item_name, :from_model
- def initialize page, page_size, operators, item_name, list_name, conf, manifest
- super
- @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
- @from = @list_list_conf['from']
- @from_model = @from.classify.constantize
- @filter_key = @list_list_conf['filter_key']
- @includes = @list_list_conf['includes']
-
- @with_model_name = @list_list_conf['with']
- end
-
- def where filter_item
- w = @model.list_where
- w += ' and ' unless w.blank?
- [w + @table_name + '.' + @filter_key + ' = ?', filter_item.id]
- end
-
- def includes
- return @includes if @includes
- w = @owner_model ? {@owner_model.item_name => {}} : {}
- w.merge({@from => {} })
- end
-
- def items filter_item
- @model.where(self.where(filter_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
- end
-
- def paginate filter_item
- Kaminari.paginate_array(Array.new(@model.where(self.where(filter_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
- end
-
- def self._add_action item_name, action_name, list_name, list_conf
- model = item_name.classify.constantize
- controller_name = model.plural + 'Controller'
- controller = controller_name.constantize
- list_list_conf = Pettanr::Application::manifest.list(item_name).lists[list_name] || {}
- from = list_list_conf['from']
- filter_model = from.classify.constantize
- filter_key = list_list_conf['filter_key']
- return if controller.method_defined?(action_name)
- controller.define_method(action_name) do
- filter_list filter_model, params
+
+ def where parent_item
+ w = @association_model.list_where
+ w += ' and ' unless w.blank?
+ [w + @association_model.table_name + '.' + @foreign_key + ' = ?', parent_item.id]
end
- end
-
- end
-
- class ThroughFilterList < FilterList
- def initialize page, page_size, operators, item_name, list_name, conf, manifest
- super
- @through = @list_list_conf['through']
- end
-
- def includes
- {@through => {@from => {}} }
- end
-
- def where filter_item
- w = @model.list_where
- w += ' and ' unless w.blank?
- [w + @through + '.' + @filter_key + ' = ?', filter_item.id]
- end
-
- end
-
- class ElementFilterList < FilterList
- def includes
- {@owner_model.item_name => {}}
- end
-
- def where filter_item
- w = @model.list_where
- w += ' and ' unless w.blank?
- [w + @owner_table_name + '.' + @filter_key + ' = ?', filter_item.id]
- end
-
- end
-
- class PlayList
- attr :params_offset, :params_count, :offset, :count, :limit
- def initialize params_offset, params_count, operators, item_name, list_name, conf, manifest
- @operators = operators
- @item_name = item_name
- @list_name = list_name
- @conf = conf
- @manifest = manifest
-
- @default_page_size = @conf['default_page_size'] || 25
- @max_page_size = @conf['max_page_size'] || 100
- @params_offset = params_offset
- @params_count = params_count
- @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
- @model_name = @list_list_conf['model']
- @filter_key = @list_list_conf['filter_key']
- @model = @model_name.classify.constantize
- @table_name = @model.table_name
- if @model.content?
- @owner_model = @model.owner_model
- @owner_table_name = @owner_model.table_name if @owner_model
+
+ def includes
+ # @with_model_name ? {@with_model_name.classify.constantize.table_name => {}} : {}
+ w = @owner_model ? {@owner_model.item_name => {}} : {}
+ w.merge({})
end
+
+ def items parent_item
+ @association_model.where(self.where(parent_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
+ end
+
+ def paginate parent_item
+ Kaminari.paginate_array(Array.new(@association_model.where(self.where(parent_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
+ end
+
+ def self._add_action item_name, action_name, list_name, list_conf
+ model = item_name.classify.constantize
+ controller_name = model.plural + 'Controller'
+ controller = controller_name.constantize
+ association_name = list_conf['association_name']
+ has_many_conf = Pettanr::Application::manifest.model(item_name).associations['has_many'] || {}
+ association_conf = has_many_conf[association_name] || {}
+ association_model_name = association_conf['model']
+ return if controller.method_defined?(action_name)
+ controller.define_method(action_name) do
+ has_many_list item_name, list_name, association_model_name, params
+ end
+ end
+
end
- def offset cnt, prm = nil
- offset = prm.to_i
- offset = cnt - 1 if offset >= cnt
- offset = cnt - offset.abs if offset < 0
- offset = 0 if offset < 0
- offset
- end
-
- def limit prm
- prm ||= @default_page_size
- count = prm.to_i
- count = @max_page_size if count > @max_page_size
- count = @default_page_size if count < 1
- count
- end
-
- def count filter_item
- @count ||= @model.count(:conditions => self.where(filter_item), :include => self.includes).to_i
- end
-
- def where filter_item
- w = @model.list_where
- w += ' and ' unless w.blank?
- [w + @table_name + '.' + @filter_key + ' = ?', filter_item.id]
+ class HasManyThroughList < BaseList
+ attr :association_model_name
+ def initialize page, page_size, operators, item_name, list_name, conf, manifest
+ super
+ @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
+ @association_name = @list_list_conf['association_name']
+ @has_many_conf = @manifest.model(@item_name).associations['has_many'] || {}
+ @association_conf = @has_many_conf[@association_name] || {}
+ @association_through_model_name = @association_conf['through']
+ @association_through_model = @association_through_model_name.classify.constantize
+ @association_model_name = @association_conf['model']
+ @association_model = @association_model_name.classify.constantize
+ @foreign_key = @association_conf['foreign_key']
+ if @association_model.content?
+ @owner_model = @association_model.owner_model
+ @owner_table_name = @owner_model.table_name if @owner_model
+ end
+ end
+
+ def where root_item
+ w = @association_model.list_where
+ w += ' and ' unless w.blank?
+ [w + @association_through_model.table_name + '.' + @foreign_key + ' = ?', root_item.id]
+ end
+
+ def includes
+ {@association_through_model.table_name => {@item_name => {}}}
+ end
+
+ def items root_item
+ @association_model.where(self.where(root_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
+ end
+
+ def paginate root_item
+ Kaminari.paginate_array(Array.new(@association_model.where(self.where(root_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
+ end
+
end
- def includes
- {@owner_model.item_name => {}}
+ class FilterList < BaseList
+ attr :item_name, :from_model
+ def initialize page, page_size, operators, item_name, list_name, conf, manifest
+ super
+ @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
+ @from = @list_list_conf['from']
+ @from_model = @from.classify.constantize
+ @filter_key = @list_list_conf['filter_key']
+ @includes = @list_list_conf['includes']
+
+ @with_model_name = @list_list_conf['with']
+ end
+
+ def self.set_default my_manifest
+ option_manifest['from'] ||= 100
+ option_manifest['filter_key'] ||= 100
+ end
+
+ def where filter_item
+ w = @model.list_where
+ w += ' and ' unless w.blank?
+ [w + @table_name + '.' + @filter_key + ' = ?', filter_item.id]
+ end
+
+ def includes
+ return @includes if @includes
+ w = @owner_model ? {@owner_model.item_name => {}} : {}
+ w.merge({@from => {} })
+ end
+
+ def items filter_item
+ @model.where(self.where(filter_item)).includes(self.includes).order(self.order).offset(@offset).limit(@page_size)
+ end
+
+ def paginate filter_item
+ Kaminari.paginate_array(Array.new(@model.where(self.where(filter_item)).includes(self.includes).count, nil)).page(@offset).per(@page_size)
+ end
+
+ def self._add_action item_name, action_name, list_name, list_conf
+ model = item_name.classify.constantize
+ controller_name = model.plural + 'Controller'
+ controller = controller_name.constantize
+ list_list_conf = Pettanr::Application::manifest.list(item_name).lists[list_name] || {}
+ from = list_list_conf['from']
+ filter_model = from.classify.constantize
+ filter_key = list_list_conf['filter_key']
+ return if controller.method_defined?(action_name)
+ controller.define_method(action_name) do
+ filter_list filter_model, params
+ end
+ end
+
end
- def order
- @table_name + '.t'
+ class ThroughFilterList < FilterList
+ def initialize page, page_size, operators, item_name, list_name, conf, manifest
+ super
+ @through = @list_list_conf['through']
+ end
+
+ def includes
+ {@through => {@from => {}} }
+ end
+
+ def where filter_item
+ w = @model.list_where
+ w += ' and ' unless w.blank?
+ [w + @through + '.' + @filter_key + ' = ?', filter_item.id]
+ end
+
end
- def items filter_item
- c = @count || self.count(filter_item)
- o = self.offset c, @offset
- l = self.limit @count
- @model.where(self.where(filter_item)).includes(self.includes).order(self.order).offset(o).limit(l)
+ class ElementFilterList < FilterList
+ def includes
+ {@owner_model.item_name => {}}
+ end
+
+ def where filter_item
+ w = @model.list_where
+ w += ' and ' unless w.blank?
+ [w + @owner_table_name + '.' + @filter_key + ' = ?', filter_item.id]
+ end
+
end
- def prev_offset filter_item
- c = @count || self.count(filter_item)
- o = self.offset c, @offset
- l = self.limit @count
- if o > 0
- if o - l < 0
- 0
+ class PlayList
+ attr :params_offset, :params_count, :offset, :count, :limit
+ def initialize params_offset, params_count, operators, item_name, list_name, conf, manifest
+ @operators = operators
+ @item_name = item_name
+ @list_name = list_name
+ @conf = conf
+ @manifest = manifest
+
+ @default_page_size = @conf['default_page_size'] || 25
+ @max_page_size = @conf['max_page_size'] || 100
+ @params_offset = params_offset
+ @params_count = params_count
+ @list_list_conf = @manifest.list(@item_name).lists[list_name] || {}
+ @model_name = @list_list_conf['model']
+ @filter_key = @list_list_conf['filter_key']
+ @model = @model_name.classify.constantize
+ @table_name = @model.table_name
+ if @model.content?
+ @owner_model = @model.owner_model
+ @owner_table_name = @owner_model.table_name if @owner_model
+ end
+ end
+
+ def offset cnt, prm = nil
+ offset = prm.to_i
+ offset = cnt - 1 if offset >= cnt
+ offset = cnt - offset.abs if offset < 0
+ offset = 0 if offset < 0
+ offset
+ end
+
+ def limit prm
+ prm ||= @default_page_size
+ count = prm.to_i
+ count = @max_page_size if count > @max_page_size
+ count = @default_page_size if count < 1
+ count
+ end
+
+ def count filter_item
+ @count ||= @model.count(:conditions => self.where(filter_item), :include => self.includes).to_i
+ end
+
+ def where filter_item
+ w = @model.list_where
+ w += ' and ' unless w.blank?
+ [w + @table_name + '.' + @filter_key + ' = ?', filter_item.id]
+ end
+
+ def includes
+ {@owner_model.item_name => {}}
+ end
+
+ def order
+ @table_name + '.t'
+ end
+
+ def items filter_item
+ c = @count || self.count(filter_item)
+ o = self.offset c, @offset
+ l = self.limit @count
+ @model.where(self.where(filter_item)).includes(self.includes).order(self.order).offset(o).limit(l)
+ end
+
+ def prev_offset filter_item
+ c = @count || self.count(filter_item)
+ o = self.offset c, @offset
+ l = self.limit @count
+ if o > 0
+ if o - l < 0
+ 0
+ else
+ o - l
+ end
else
- o - l
+ nil
end
- else
- nil
+ end
+
+ def next_offset filter_item
+ c = @count || self.count(filter_item)
+ o = self.offset c, @offset
+ l = self.limit @count
+ if o + l > c
+ nil
+ else
+ o + l
+ end
+ end
+
+ def self.add_action item_name, action_name, list_name, list_conf
+ return
end
end
- def next_offset filter_item
- c = @count || self.count(filter_item)
- o = self.offset c, @offset
- l = self.limit @count
- if o + l > c
- nil
- else
- o + l
+ @@types = {
+ 'public' => PublicList, 'private' => PrivateList, 'system_resource' => SystemResourceList,
+ 'has_many' => HasManyList, 'has_many_through' => HasManyThroughList, 'filter' => FilterList,
+ 'through_filter' => ThroughFilterList, 'element_filter' => ElementFilterList,
+ 'play' => PlayList
+ }
+ def initialize list_manifest
+ @list_manifest = list_manifest
+ @item_name = @list_manifest.item_name
+ @manifest = @list_manifest.manifest
+ @list_conf = @list_manifest.conf
+ @lists = {}
+ @list_manifest.lists.each {|list_name, conf|
+ type = conf['type']
+ @lists[list_name] = @@types[type]
+ }
+ end
+
+ def open list_name, page, page_size, operators
+ raise "undefined list for #{@item_name}::#{list_name}\nconf:#{@list_conf}\n" unless @lists[list_name]
+ @lists[list_name].new page, page_size, operators, @item_name, list_name, @list_conf, @manifest
+ end
+
+ def filer opt = nil
+ paginate = opt ? @list.paginate(opt) : @list.paginate
+ @filer ||= @manifest.filer_managers[@item_name].open(@item_name, @items, @operators, paginate)
end
+
+ def add_action action_name, list_name
+ @lists[list_name].add_action @item_name, action_name, list_name, @list_conf
end
- def self.add_action item_name, action_name, list_name, list_conf
- return
- end
- end
-
- @@types = {
- 'public' => PublicList, 'private' => PrivateList, 'system_resource' => SystemResourceList,
- 'has_many' => HasManyList, 'has_many_through' => HasManyThroughList, 'filter' => FilterList,
- 'through_filter' => ThroughFilterList, 'element_filter' => ElementFilterList,
- 'play' => PlayList
- }
- def initialize list_manifest
- @list_manifest = list_manifest
- @item_name = @list_manifest.item_name
- @manifest = @list_manifest.manifest
- @list_conf = @list_manifest.conf
- @lists = {}
- @list_manifest.lists.each {|list_name, conf|
- type = conf['type']
- @lists[list_name] = @@types[type]
- }
- end
-
- def open list_name, page, page_size, operators
- raise "undefined list for #{@item_name}::#{list_name}\nconf:#{@list_conf}\n" unless @lists[list_name]
- @lists[list_name].new page, page_size, operators, @item_name, list_name, @list_conf, @manifest
- end
-
- def add_action action_name, list_name
- @lists[list_name].add_action @item_name, action_name, list_name, @list_conf
end
-
end
end