OSDN Git Service

fx Manifest
authoryasushiito <yas@pen-chan.jp>
Fri, 10 Jan 2014 06:55:51 +0000 (15:55 +0900)
committeryasushiito <yas@pen-chan.jp>
Fri, 10 Jan 2014 06:55:51 +0000 (15:55 +0900)
app/assets/javascripts/manifest/work/controllers.js.coffee.erb
app/assets/javascripts/manifest/work/lists.js.coffee.erb
app/controllers/comics_controller.rb
lib/manifest/controller.rb
lib/manifest/list.rb
lib/manifest/manifest.rb
lib/manifest/model.rb

index 2d24d2a..caf24e9 100644 (file)
@@ -1,17 +1,17 @@
 #マニフェスト\r
 @controllers = {\r
   scroll: {\r
-    model_name: 'scroll',\r
+    item_name: 'scroll',\r
     actions: {\r
       index: {\r
         type: 'list',\r
-        list: {\r
+        options: {\r
           list_name: 'public_list',\r
         },\r
       },\r
       scroll_panels: {\r
         type: 'list',\r
-        list: {\r
+        options: {\r
           list_name: 'scroll_panels',\r
         },\r
       },\r
index 9701afd..99ef80c 100644 (file)
@@ -1,39 +1,35 @@
 #マニフェスト\r
 @lists = {\r
   scroll: {\r
-    default_page_size: 25, \r
-    max_page_size: 100, \r
-    lists: {\r
-      public_list: {\r
-        type: 'public',\r
-      },\r
-      private_list: {\r
-        type: 'private',\r
-      },\r
-      scroll_panels: {\r
-        type: 'has_many',\r
-        association_name: 'scroll_panels',\r
-      },\r
-      panels: {\r
-        type: 'has_many_through',\r
-        association_name: 'panels',\r
-      },\r
-      by_author: {\r
-        type: 'filter',\r
-        from: 'author',\r
-        filter_key: 'author_id',\r
-      },\r
-      by_panel: {\r
-        type: 'through_filter',\r
-        from: 'panel',\r
-        through: 'scroll_panels',\r
-        filter_key: 'panel_id',\r
-      },\r
-      play: {\r
-        type: 'play',\r
-        model: 'scroll_panel',\r
-        filter_key: 'scroll_id',\r
-      },\r
+    public_list: {\r
+      type: 'public',\r
+    },\r
+    private_list: {\r
+      type: 'private',\r
+    },\r
+    scroll_panels: {\r
+      type: 'has_many',\r
+      association_name: 'scroll_panels',\r
+    },\r
+    panels: {\r
+      type: 'has_many_through',\r
+      association_name: 'panels',\r
+    },\r
+    by_author: {\r
+      type: 'filter',\r
+      from: 'author',\r
+      filter_key: 'author_id',\r
+    },\r
+    by_panel: {\r
+      type: 'through_filter',\r
+      from: 'panel',\r
+      through: 'scroll_panels',\r
+      filter_key: 'panel_id',\r
+    },\r
+    play: {\r
+      type: 'play',\r
+      model: 'scroll_panel',\r
+      filter_key: 'scroll_id',\r
     },\r
   },\r
   scroll_panel: {\r
index ddf0b06..10b9e1b 100644 (file)
@@ -14,6 +14,8 @@ class ComicsController < ApplicationController
   end
   
   def index
+    @action = self.class.controller.open(action_name, params, @operators)
+    @action.cook params, operators
     public_list
   end
 
index b074ac1..6f26f45 100644 (file)
 
 module Pettanr
-  class ControllerManager
-    class ActionList
-      attr :list
-      def initialize action_name, item_name, operators, list, conf, manifest
-        @action_name = action_name
-        @item_name = item_name
-        @operators = operators
-        @list = list
-        @conf = conf
-        @manifest = manifest
+  module Manifest
+    class Controller
+      def self.set_default my_manifest
+        my_manifest.each {|item_name, controller_manifest|
+          controller_manifest|['model_name'] ||= item_name
+          controller_manifest|['actions'] ||= {}
+          controller_manifest|['actions'].each {|action_name, action_manifest|
+            action_manifest['options'] ||= {}
+            action_manifest['options'].each {option_name, option_manifest|
+              raise "undefined list_name for controllers > #{item_name} > actions > #{action_name} > options\n" unless option_manifest['list_name']
+            }
+          }
+        }
       end
       
-      def items 
-        @items ||= @list.items
+      class ActionList
+        attr :list
+        def initialize my_item_name, action_name, conf
+          # get home list_name
+          @my_item_name = conf['item_name'] if conf['item_name']
+          @action_name = action_name
+          @conf = conf
+        end
+        
+        def list params, operators
+          list_name = @controller_manifest.list_name action_name
+          @list = @manifest.list_managers[@my_item_name].open(list_name, params[:page], params[:page_size], operators)
+        end
+        
+        def ready params, operators
+          @items = @action.items 
+          
+        end
+        
+        def exec
+        end
+        
+        def render
+          format.html {
+            @filer = @action.filer
+            render :template => 'system/filer', :locals => {
+              :filer => @filer
+            }
+          }
+        end
+        
+        def cook params, operators
+          @action.ready params, operators
+          @action.exec
+          @action.render
+        end
+        
       end
       
-      def filer opt =  nil
-        paginate = opt ? @list.paginate(opt) : @list.paginate
-        @filer ||= @manifest.filer_managers[@item_name].open(@item_name, @items, @operators, paginate)
+      class ActionShow
+        def initialize my_item_name, action_name, conf
+          @my_item_name = conf['item_name'] if conf['item_name']
+          @action_name = action_name
+          @conf = conf
+        end
+        
+        def ready
+          @item = Comic.show(params[:id], @operators)
+        end
+        
+        def exec
+        end
+        
+        def render
+          format.html {
+          }
+        end
+        
       end
       
-    end
-    
-    class ActionShow
-      def initialize action_name, item_name, conf, manifest
-        @action_name = action_name
-        @item_name = item_name
-        @conf = conf
-        @manifest = manifest
-        
+      class Recipe
       end
       
-    end
-    
-    attr :controller_manifest, :item_name, :manifest, :controller_conf, 
-      :actions
-    @@types = {'list' => ActionList, 'show' => ActionShow}
-    def initialize controller_manifest
-      @controller_manifest = controller_manifest
-      @item_name = @controller_manifest.item_name
-      @manifest = @controller_manifest.manifest
-      @controller_conf = @controller_manifest.conf
-      @actions = {}
-      @controller_manifest.actions.each {|action_name, conf|
-        type = conf['type']
-        @actions[action_name] = @@types[type]
-      }
-    end
-    
-    def open action_name, params, operators
-      name = if @controller_manifest.actions[action_name]['item_name']
-        @controller_manifest.actions[action_name]['item_name']
-      else
-        @item_name
+      attr :controller_manifest, :item_name, :manifest, :controller_conf, 
+        :actions
+      @@types = {'list' => ActionList, 'show' => ActionShow}
+      def initialize controller_manifest
+        @controller_manifest = controller_manifest
+        @item_name = @controller_manifest.item_name
+        @manifest = @controller_manifest.manifest
+        @controller_conf = @controller_manifest.conf
+        @actions = {}
+        @my_item_name = @controller_conf['item_name'] || @item_name
+        @controller_manifest.actions.each {|action_name, conf|
+          type = conf['type']
+          @actions[action_name] = @@types[type].new @my_item_name, action_name, conf
+        }
       end
-      list_name = @controller_manifest.list_name action_name
-      @list = @manifest.list_managers[name].open(list_name, params[:page], params[:page_size], operators)
-      raise "undefined controller for #{@item_name}::#{action_name}\nconf:#{@controller_conf}\n" unless @actions[action_name]
-      @actions[action_name].new action_name, name, operators, @list, @controller_conf, @manifest
+      
+      
     end
-    
   end
 end
 
index cec7640..06c62ff 100644 (file)
 
 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
 
index ae575c9..0fb89ca 100644 (file)
@@ -1,40 +1,6 @@
 
 module Pettanr
-  class Manifest
-    class Controller
-      attr :item_name, :conf, :manifest, :model_name, :actions
-      def initialize item_name, conf, manifest
-        @item_name = item_name
-        @conf = conf || {}
-        @manifest = manifest
-        @model_name = @conf['model_name']
-        @actions = @conf['actions'] || {}
-      end
-      
-      def list_name action_name
-        a = @actions[action_name] || {}
-        l = a['list'] || {}
-        l['list_name']
-      end
-      
-    end
-    
-    class Model
-      attr :item_name, :conf, :manifest, :attributes, :associations, :belongs_to, :has_many, :has_one
-      def initialize item_name, conf, manifest
-        @item_name = item_name
-        @conf = conf || {}
-        @manifest = manifest
-        
-        @attributes = @conf['attributes']
-        @associations = @conf['associations'] || {}
-        @belongs_to = @associations['belongs_to'] || {}
-        @has_many = @associations['has_many'] || {}
-        @has_one = @associations['has_one'] || {}
-      end
-      
-    end
-    
+  module Manifest
     class List
       attr :item_name, :conf, :manifest, :default_page_size, :lists
       def initialize item_name, conf, manifest
@@ -105,6 +71,7 @@ module Pettanr
       
     end
     
+  class Manifest
     attr :system_resources, :magic_numbers, :select_items,
       :controller_managers, :model_managers, :list_managers, :profiler_managers, :filer_managers, :form_managers
     def initialize manifest
@@ -112,9 +79,9 @@ module Pettanr
       @system_resources = SystemResources.new(@manifest['system_resources'])
       @magic_numbers = @manifest['magic_numbers']
       @select_items = @manifest['select_items']
-      @controllers = {}
-      @models = {}
-      @lists = {}
+      @controllers = Controller.set_default(@manifest['controllers'] || {})
+      @models = Model.set_default(@manifest['models'] || {})
+      @lists = List.set_default(@manifest['lists'] || {})
       @profilers = {}
       @filers = {}
       @forms = {}
index c3dbf20..d414bb1 100644 (file)
@@ -1,16 +1,51 @@
 
 module Pettanr
-  class ModelManager
-    def initialize model_manifest
-      @model_manifest = model_manifest
-      @item_name = @model_manifest.item_name
-      @manifest = @model_manifest.manifest
-      @model_conf = @model_manifest.conf
+  module Manifest
+    class Model
+      def self.set_default my_manifest
+        my_manifest.each {|item_name, model_manifest|
+          model_manifest['attributes'] ||= {}
+          model_manifest['associations'] ||= {}
+          model_manifest|['attributes'].each {|attribute_name, attribute_manifest|
+            attribute_manifest.each {|attribute_name, attribute_manifest|
+              raise "undefined type for models > #{item_name} > attributes > #{attribute_name}\n" unless attribute_manifest['type']
+              attribute_manifest['primary_key'] ||= 0
+              attribute_manifest['rules'] ||= {}
+              attribute_manifest['rules'].each {|rule_name, rule_manifest|
+                # 'required' 'number'
+              }
+            }
+          }
+          model_manifest|['associations'].each {|association_name, association_manifest|
+            association_manifest['belongs_to'] ||= {}
+            association_manifest['has_many'] ||= {}
+            association_manifest['has_one'] ||= {}
+            association_manifest['belongs_to'].each {|belongs_to_name, belongs_to_manifest|
+              belongs_to_manifest['id_column'] ||= belongs_to_name + '_id' 
+            }
+            association_manifest['has_many'].each {|has_many_name, has_many_manifest|
+              raise "undefined foreign_key for models > #{item_name} > associations > has_many > #{has_many_name}\n" unless has_many_manifest['foreign_key']
+              has_many_manifest['model'] ||= has_many_name.singularize
+              # 'through'
+            }
+            association_manifest['belongs_to'].each {|belongs_to_name, belongs_to_manifest|
+              belongs_to_manifest['id_column'] ||= belongs_to_name + '_id' 
+            }
+          }
+        }
+      end
+      
+      def initialize model_manifest
+        @model_manifest = model_manifest
+        @item_name = @model_manifest.item_name
+        @manifest = @model_manifest.manifest
+        @model_conf = @model_manifest.conf
+      end
+      
+      def open list_name, page, page_size, operators
+      end
+      
     end
-    
-    def open list_name, page, page_size, operators
-    end
-    
   end
 end