OSDN Git Service

add comic story
authoryasushiito <yas@pen-chan.jp>
Fri, 23 May 2014 08:04:15 +0000 (17:04 +0900)
committeryasushiito <yas@pen-chan.jp>
Fri, 23 May 2014 08:04:15 +0000 (17:04 +0900)
42 files changed:
app/assets/images/comic_story.gif [new file with mode: 0644]
app/assets/javascripts/comic_stories.js.coffee [new file with mode: 0644]
app/assets/javascripts/manifest/work/controllers.js.coffee.erb
app/assets/javascripts/manifest/work/filers.js.coffee.erb
app/assets/javascripts/manifest/work/forms.js.coffee.erb
app/assets/javascripts/manifest/work/items.js.coffee.erb
app/assets/javascripts/manifest/work/list_groups.js.coffee.erb
app/assets/javascripts/manifest/work/models.js.coffee.erb
app/assets/javascripts/manifest/work/profilers.js.coffee.erb
app/assets/stylesheets/comic_stories.css.scss [new file with mode: 0644]
app/controllers/comic_stories_controller.rb [new file with mode: 0644]
app/controllers/comics_controller.rb
app/controllers/sheets_controller.rb
app/controllers/stories_controller.rb
app/helpers/comic_stories_helper.rb [new file with mode: 0644]
app/models/comic.rb
app/models/comic_story.rb [new file with mode: 0644]
app/models/folder.rb
app/models/story.rb
app/views/comic_stories/_append_panel.html.erb [new file with mode: 0644]
app/views/comic_stories/_append_scroll.html.erb [new file with mode: 0644]
app/views/comic_stories/_footer.html.erb [new file with mode: 0644]
app/views/comic_stories/_form.html.erb [new file with mode: 0644]
app/views/comic_stories/_licensed_pictures.html.erb [new file with mode: 0644]
app/views/comic_stories/_order.html.erb [new file with mode: 0644]
app/views/comic_stories/_scroll_header.html.erb [new file with mode: 0644]
app/views/comic_stories/_summary.html.erb [new file with mode: 0644]
app/views/comic_stories/edit.html.erb [new file with mode: 0644]
app/views/comic_stories/new.html.erb [new file with mode: 0644]
app/views/comics/_summary.html.erb
app/views/stories/_summary.html.erb
app/views/stories/show.html.erb
config/locales/pettanr.ja.yml
config/routes.rb
db/migrate/20140519235843_create_comic_stories.rb [new file with mode: 0644]
db/migrate/20140520102407_rm_comic_id_on_story.rb [new file with mode: 0644]
public/images/comic_story.gif [new file with mode: 0644]
public/local_manifest.json
public/manifest.json
spec/controllers/comic_stories_controller_spec.rb [new file with mode: 0644]
spec/helpers/comic_stories_helper_spec.rb [new file with mode: 0644]
spec/models/comic_story_spec.rb [new file with mode: 0644]

diff --git a/app/assets/images/comic_story.gif b/app/assets/images/comic_story.gif
new file mode 100644 (file)
index 0000000..0707502
Binary files /dev/null and b/app/assets/images/comic_story.gif differ
diff --git a/app/assets/javascripts/comic_stories.js.coffee b/app/assets/javascripts/comic_stories.js.coffee
new file mode 100644 (file)
index 0000000..7615679
--- /dev/null
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
index 1c9abaf..eda0191 100644 (file)
           \r
         },\r
       },\r
+      by_story: {\r
+        type: 'list',\r
+      },\r
       by_author: {\r
         type: 'list',\r
       },\r
           list_name: 'public',\r
         },\r
       },\r
+      count_by_story: {\r
+        type: 'count',\r
+      },\r
+      count_by_author: {\r
+        type: 'count',\r
+      },\r
+      new: {\r
+        type: 'new',\r
+      },\r
+      edit: {\r
+        type: 'edit',\r
+      },\r
+    },\r
+  },\r
+  comic_stories: {\r
+    actions: {\r
+      index: {\r
+        type: 'list',\r
+        args: {\r
+          list_name: 'public',\r
+          \r
+        },\r
+      },\r
+      by_comic: {\r
+        type: 'list',\r
+      },\r
+      by_story: {\r
+        type: 'list',\r
+      },\r
+      by_author: {\r
+        type: 'list',\r
+      },\r
+      show: {\r
+        type: 'show',\r
+      },\r
+      count: {\r
+        type: 'count',\r
+        args: {\r
+          list_name: 'public',\r
+        },\r
+      },\r
+      count_by_comic: {\r
+        type: 'count',\r
+      },\r
+      count_by_story: {\r
+        type: 'count',\r
+      },\r
       count_by_author: {\r
         type: 'count',\r
       },\r
           list_name: 'public',\r
         },\r
       },\r
-      by_comic: {\r
+      count_by_comic: {\r
         type: 'count',\r
       },\r
-      by_sheet: {\r
+      count_by_sheet: {\r
         type: 'count',\r
       },\r
       count_by_author: {\r
index 2ac275d..c10123b 100644 (file)
     edit: {\r
     },\r
   },\r
+  comic_story: {\r
+    symbol: {\r
+      type: 'default',\r
+      args: {\r
+        link: {\r
+          type: 'none',\r
+        },\r
+      },\r
+    },\r
+    caption: {\r
+      type: 'none',\r
+    },\r
+    summary: {\r
+    },\r
+    edit: {\r
+      type: 'none',\r
+    },\r
+  },\r
   story: {\r
     symbol: {\r
     },\r
       type: 'default',\r
       args: {\r
         face: {\r
-          type: 'method',\r
+          type: 'column',\r
           args: {\r
-            method_name: 'title_with_t',\r
+            column_name: 'title',\r
           },\r
         },\r
         link: {\r
index 89561e5..db99caf 100644 (file)
       'author_id',\r
     ]\r
   },\r
-  story: {\r
+  comic_story: {\r
     fields: {\r
       comic_id: {\r
+        tag: {\r
+          type: 'number',\r
+        },\r
+      },\r
+      story_id: {\r
+        tag: {\r
+          type: 'number',\r
+        },\r
+      },\r
+      t: {\r
+        tag: {\r
+          type: 'number',\r
+        },\r
+      },\r
+      id: {\r
         label: {\r
           type: 'none',\r
         },\r
           type: 'hidden',\r
         },\r
       },\r
+    },\r
+    field_names: [\r
+      'comic_id',\r
+      'story_id',\r
+      't',\r
+      'id',\r
+    ]\r
+  },\r
+  story: {\r
+    fields: {\r
       title: {\r
         label: {\r
           args: {\r
         },\r
         row_break: true,\r
       },\r
-      t: {\r
-        tag: {\r
-          type: 'number',\r
-        },\r
-      },\r
       id: {\r
         label: {\r
           type: 'none',\r
       },\r
     },\r
     field_names: [\r
-      'comic_id',\r
       'title',\r
       'description',\r
       'visible',\r
-      't',\r
       'id',\r
       'author_id',\r
     ]\r
index 7148036..60c6351 100644 (file)
     args: {\r
     },\r
   },\r
+  comic_story: {\r
+    type: 'leaf',\r
+    args: {\r
+      parent_model_name: 'comic',\r
+    },\r
+  },\r
   story: {\r
     type: 'binder',\r
     args: {\r
index 54b73aa..9431400 100644 (file)
       by_author: {\r
         type: 'filter',\r
       },\r
+      by_story: {\r
+        type: 'through_filter',\r
+        args: {\r
+          through: 'comic_stories',\r
+        },\r
+      },\r
     },\r
   },\r
-  story: {\r
+  comic_story: {\r
     lists: {\r
       public: {\r
         type: 'public',\r
       private: {\r
         type: 'private',\r
       },\r
+      play: {\r
+        type: 'play',\r
+        args: {\r
+          filter_item_name: 'comic',\r
+          filter_model_name: 'comic_story',\r
+          filter_key: 'comic_id',\r
+        },\r
+      },\r
       by_comic: {\r
         type: 'filter',\r
       },\r
-      by_sheet: {\r
-        type: 'through_filter',\r
-        args: {\r
-          through: 'story_sheets',\r
-        },\r
+      by_story: {\r
+        type: 'filter',\r
       },\r
       by_author: {\r
         type: 'foreign_filter',\r
           },\r
         },\r
       },\r
-      play: {\r
-        type: 'play',\r
+    },\r
+  },\r
+  story: {\r
+    lists: {\r
+      public: {\r
+        type: 'public',\r
+      },\r
+      private: {\r
+        type: 'private',\r
+      },\r
+      by_comic: {\r
+        type: 'through_filter',\r
+        args: {\r
+          through: 'comic_stories',\r
+        },\r
+      },\r
+      by_sheet: {\r
+        type: 'through_filter',\r
+        args: {\r
+          through: 'story_sheets',\r
+        },\r
+      },\r
+      by_author: {\r
+        type: 'filter',\r
       },\r
     },\r
   },\r
index 58cdd7f..cb668d8 100644 (file)
@@ -74,7 +74,7 @@
         scroll_panels: {\r
         }, \r
         panels: {\r
-          through: 'scroll_panel',\r
+          through: 'scroll_panels',\r
         }, \r
       },\r
     },\r
         }, \r
       },\r
       has_many: {\r
+        comic_stories: {\r
+        }, \r
         stories: {\r
+          through: 'comic_stories',\r
         }, \r
       },\r
     },\r
       },\r
     },\r
   },\r
-  story: {\r
+  comic_story: {\r
     associations: {\r
       belongs_to: {\r
         comic: {\r
         }, \r
+        story: {\r
+        }, \r
       },\r
       has_many: {\r
-        story_sheets: {\r
-        }, \r
-        sheets: {\r
-          through: 'story_sheets',\r
-        }, \r
       },\r
     },\r
     attributes: {\r
       comic_id: {\r
         type: 'number',\r
         rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+      story_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+      t: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+          min: 0,\r
+        }\r
+      },\r
+      author_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
           number: true,\r
         }\r
       },\r
+    },\r
+  },\r
+  story: {\r
+    associations: {\r
+      belongs_to: {\r
+      },\r
+      has_many: {\r
+        comic_stories: {\r
+        }, \r
+        comics: {\r
+          through: 'comic_stories',\r
+        }, \r
+        story_sheets: {\r
+        }, \r
+        sheets: {\r
+          through: 'story_sheets',\r
+        }, \r
+      },\r
+    },\r
+    attributes: {\r
       title: {\r
         type: 'text',\r
         rules : {\r
           },\r
         },\r
       },\r
+      author_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
     },\r
   },\r
   story_sheet: {\r
index f4280e3..5cc894b 100644 (file)
         'author',\r
       ],\r
       has_many: [\r
+        'comic_stories.by_comic', \r
         'stories.by_comic', \r
       ],\r
     }, \r
   },\r
-  story: {\r
+  comic_story: {\r
     column_names: [\r
       'comic_id', \r
+      'story_id', \r
+      't', \r
+    ],\r
+    associations: {\r
+      belongs_to: [\r
+        'comic', \r
+        'story'\r
+      ],\r
+    }, \r
+  },\r
+  story: {\r
+    column_names: [\r
       'title', \r
       'description', \r
       't', \r
     ],\r
     associations: {\r
       belongs_to: [\r
-        'comic',\r
       ],\r
       has_many: [\r
+        'comic_stories.by_story', \r
+        'comics.by_story',\r
         'story_sheets.by_story', \r
         'sheets.by_story'\r
       ],\r
         'scrolls.by_author', \r
         'scroll_panels.by_author', \r
         'comics.by_author', \r
+        'comic_stories.by_author', \r
         'stories.by_author', \r
         'sheets.by_author', \r
         'sheet_panels.by_author', \r
diff --git a/app/assets/stylesheets/comic_stories.css.scss b/app/assets/stylesheets/comic_stories.css.scss
new file mode 100644 (file)
index 0000000..ee7577e
--- /dev/null
@@ -0,0 +1,3 @@
+// Place all the styles related to the comic_stories controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/comic_stories_controller.rb b/app/controllers/comic_stories_controller.rb
new file mode 100644 (file)
index 0000000..bcc8df1
--- /dev/null
@@ -0,0 +1,120 @@
+class ComicStoriesController < ApplicationController
+  if Manifest.manifest.magic_numbers['run_mode'] == 0
+    before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy]
+    before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy]
+  else
+    before_filter :authenticate_reader, :only => [
+      :index, :show, :by_story, :by_comic, :by_author, :count, :count_by_story, :count_by_comic, :count_by_author
+    ]
+    before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy]
+    before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy]
+  end
+
+  def self.model
+    ComicStory
+  end
+  
+  def index
+    filer_list
+  end
+  
+  def by_story
+    filer_list
+  end
+  
+  def by_comic
+    filer_list
+  end
+  
+  def by_author
+    filer_list
+  end
+  
+  def show
+    set_show
+    respond_to do |format|
+      show_prof_format format
+      format.json { render json: @item.comic_story_as_json(@operators.author) }
+    end
+  end
+  
+  def count
+    list_count
+  end
+  
+  def count_by_story
+    list_count
+  end
+  
+  def count_by_comic
+    list_count
+  end
+  
+  def count_by_author
+    list_count
+  end
+  
+  def new
+    form_new
+  end
+  
+  def edit
+    form_edit
+  end
+  
+  def create
+    @comic_story = ComicStory.new 
+    @comic_story.supply_default
+    @comic_story.attributes = params[:comic_story]
+    @comic_story.overwrite @operators
+    @comic = Comic.edit(@comic_story.comic_id, @operators) if @comic_story.comic_id
+    @story = Story.show(@comic_story.story_id, @operators) if @comic_story.story_id
+    
+    respond_to do |format|
+      if @comic_story.store @operators
+        flash[:notice] = I18n.t('flash.notice.created', :model => ComicStory.model_name.human)
+        format.html { redirect_to play_comic_path(@comic) }
+        format.json { render json: @comic_story.comic_story_as_json(@operators.author) }
+      else
+        flash[:notice] = I18n.t('flash.notice.not_created', :model => ComicStory.model_name.human)
+        format.html { render action: "new" }
+        format.json { render json: @comic_story.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+  
+  def update
+    @comic_story = ComicStory.edit(params[:id], @operators)
+    ot = @comic_story.t
+    @comic_story.attributes = params[:comic_story]
+    @comic_story.overwrite @operators
+    @comic = Comic.edit(@comic_story.comic_id, @operators) if @comic_story.comic_id
+    respond_to do |format|
+      if @comic_story.store @operators, ot
+        flash[:notice] = I18n.t('flash.notice.updated', :model => ComicStory.model_name.human)
+        format.html { redirect_to play_comic_path(@comic) }
+        format.json { head :ok }
+      else
+        flash[:notice] = I18n.t('flash.notice.not_updated', :model => ComicStory.model_name.human)
+        format.html { render action: "edit" }
+        format.json { render json: @comic_story.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  def destroy
+    @comic_story = ComicStory.edit(params[:id], @operators)
+    @comic = Comic.edit(@comic_story.comic_id, @operators) if @comic_story.comic_id
+    respond_to do |format|
+      if @comic_story.destroy_and_shorten
+        flash[:notice] = I18n.t('flash.notice.destroyed', :model => ComicStory.model_name.human)
+        format.html { redirect_to play_comic_path(@comic) }
+        format.json { head :ok }
+      else
+        flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => ComicStory.model_name.human)
+        format.html { redirect_to comic_story_path(@comic_story) }
+        format.json { render json: @comic_story.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+end
index 5a5312b..0d370ca 100644 (file)
@@ -3,7 +3,7 @@ class ComicsController < ApplicationController
     before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy]
     before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy]
   else
-    before_filter :authenticate_reader, :only => [:index, :show, :by_author, :count, :count_by_author]
+    before_filter :authenticate_reader, :only => [:index, :show, :by_story, :by_author, :count, :count_by_story, :count_by_author]
     before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy]
     before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy]
   end
@@ -15,11 +15,15 @@ class ComicsController < ApplicationController
   def index
     filer_list
   end
-
+  
+  def by_story
+    filer_list
+  end
+  
   def by_author
     filer_list
   end
-
+  
   def show_html_format format
     format.html {
     }
@@ -35,11 +39,15 @@ class ComicsController < ApplicationController
       format.rss 
     end
   end
-
+  
   def count
     list_count
   end
   
+  def count_by_story
+    list_count
+  end
+  
   def count_by_author
     list_count
   end
index 2f24813..0141b20 100644 (file)
@@ -103,7 +103,7 @@ class SheetsController < ApplicationController
       jsn = JSON.parse_no_except(params[:json])
     end
     @prm = params[:sheet] || jsn
-
+    
     respond_to do |format|
       if @sheet.store @prm, @operators
         flash[:notice] = I18n.t('flash.notice.created', :model => Sheet.model_name.human)
@@ -116,7 +116,7 @@ class SheetsController < ApplicationController
       end
     end
   end
-
+  
   def update
     @sheet = Sheet.edit(params[:id], @operators)
     jsn = nil
@@ -136,7 +136,7 @@ class SheetsController < ApplicationController
       end
     end
   end
-
+  
   def destroy
     @sheet = Sheet.edit(params[:id], @operators)
     respond_to do |format|
index 0765171..f6beb21 100644 (file)
@@ -99,17 +99,19 @@ class StoriesController < ApplicationController
   end
   
   def create
-    @story = Story.new 
-    @story.supply_default
-    @story.attributes = params[:story]
-    @story.overwrite
-    @comic = Comic.edit(@story.comic_id, @operators) if @story.comic_id
+    @story = Story.new
+    @story.supply_default 
+    jsn = nil
+    if params[:json]
+      jsn = JSON.parse_no_except(params[:json])
+    end
+    @prm = params[:story] || jsn
     
     respond_to do |format|
-      if @story.store @operators
+      if @story.store @prm, @operators
         flash[:notice] = I18n.t('flash.notice.created', :model => Story.model_name.human)
-        format.html { redirect_to play_story_path(@story, :page => @story.t.to_i + 1) }
-        format.json { render json: @story.to_json(Story.show_json_opt) }
+        format.html { redirect_to @story }
+        format.json { render json: @story.to_json(Story.show_json_opt), status: :created, location: @story }
       else
         flash[:notice] = I18n.t('flash.notice.not_created', :model => Story.model_name.human)
         format.html { render action: "new" }
@@ -120,13 +122,15 @@ class StoriesController < ApplicationController
   
   def update
     @story = Story.edit(params[:id], @operators)
-    ot = @story.t
-    @story.attributes = params[:story]
-    @story.overwrite
+    jsn = nil
+    if params[:json]
+      jsn = JSON.parse(params[:json])
+    end
+    @prm = params[:story] || jsn
     respond_to do |format|
-      if @story.store @operators, ot
+      if @story.store @prm, @operators
         flash[:notice] = I18n.t('flash.notice.updated', :model => Story.model_name.human)
-        format.html { redirect_to play_story_path(@story, :page => @story.t.to_i + 1) }
+        format.html { redirect_to @story }
         format.json { head :ok }
       else
         flash[:notice] = I18n.t('flash.notice.not_updated', :model => Story.model_name.human)
@@ -135,19 +139,20 @@ class StoriesController < ApplicationController
       end
     end
   end
-
+  
   def destroy
     @story = Story.edit(params[:id], @operators)
     respond_to do |format|
-      if @story.destroy_and_shorten
+      if @story.destroy_with_story_panel
         flash[:notice] = I18n.t('flash.notice.destroyed', :model => Story.model_name.human)
-        format.html { redirect_to comic_path(@story.comic)}
+        format.html { redirect_to '/home/stories' }
         format.json { head :ok }
       else
         flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => Story.model_name.human)
-        format.html { redirect_to story_path(@story) }
+        format.html { redirect_to @story }
         format.json { render json: @story.errors, status: :unprocessable_entity }
       end
     end
   end
+  
 end
diff --git a/app/helpers/comic_stories_helper.rb b/app/helpers/comic_stories_helper.rb
new file mode 100644 (file)
index 0000000..93633f0
--- /dev/null
@@ -0,0 +1,2 @@
+module ComicStoriesHelper
+end
index 5b7f9dc..86c28e5 100644 (file)
@@ -1,7 +1,7 @@
 #コミック
 class Comic < Peta::Content
   load_manifest
-  has_many :stories, :order => 't'
+  has_many :comic_stories
   belongs_to :author
   
   validates :title, :presence => true, :length => {:maximum => 100}
@@ -32,10 +32,6 @@ class Comic < Peta::Content
     end
   end
   
-  def comic_stories_count
-    Story.where(['stories.comic_id = ?', self.id]).count
-  end
-  
   def symbol_filename
   end
   
@@ -48,19 +44,19 @@ class Comic < Peta::Content
   end
   
   def self.list_opt
-    {:stories => {}, :author => {} }
+    {:comic_stories => {:story => {}}, :author => {} }
   end
   
   def self.list_json_opt
-    {:include => {:stories => {}, :author => {}} }
+    {:include => {:comic_stories => {:include => {:story => {}}}, :author => {}}}
   end
   
   def self.show_opt
-    {:include => {:stories => {}, :author => {}} }
+    {:include => {:comic_stories => {:story => {}}, :author => {}}}
   end
   
   def self.show_json_opt
-    {:include => {:stories => {}, :author => {}} }
+    {:include => {:comic_stories => {:include => {:story => {}}}, :author => {}}}
   end
   
   def tag_attributes column = nil, opt = {}
diff --git a/app/models/comic_story.rb b/app/models/comic_story.rb
new file mode 100644 (file)
index 0000000..bcde23a
--- /dev/null
@@ -0,0 +1,166 @@
+class ComicStory < Peta::Leaf
+  load_manifest
+  belongs_to :author
+  belongs_to :comic
+  belongs_to :story
+  
+  validates :comic_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :story_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
+  
+  def supply_default
+    self.comic_id = nil
+    self.story_id = nil
+    self.t = nil
+  end
+  
+  def overwrite operators
+    return false unless operators.author
+    self.author_id = operators.author.id
+  end
+  
+  def self.public_list_order
+    'comic_stories.updated_at desc'
+  end
+  
+  def self.list_where
+    'comics.visible > 0'
+  end
+  
+  def self.by_author_list_includes
+    {
+      :comic => {
+        :author => {}
+      }
+    }
+  end
+  
+  def self.play_list_where cid
+    ['comic_stories.comic_id = ?', cid]
+  end
+  
+  def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size
+    ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit)
+  end
+  
+  def self.list_opt
+    {
+      :comic => {
+        :author => {}, 
+      }
+    }
+  end
+  
+  def self.list_json_opt
+    {:include => {
+      :comic => {
+        :author => {}, 
+      }
+    }}
+  end
+  
+  def self.show_opt
+    {:include => {
+      :comic => {
+      }
+    }}
+  end
+  
+  def self.new_t comic_id
+    r = Story.max_t(comic_id)
+    r.blank? ? 0 : r.to_i + 1
+  end
+  
+  def self.max_t comic_id
+    Story.maximum(:t, :conditions => ['comic_id = ?', comic_id])
+  end
+  
+  def self.find_t comic_id, t
+    Story.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
+  end
+  
+  def self.collect_t story
+    r = Story.find(:all, :conditions => ['comic_id = ?', story.comic_id], :order => 't')
+    r.map {|s| s.t}
+  end
+  
+  def self.serial? ary
+    i = 0
+    ary.compact.sort.each do |t|
+      break false unless t == i
+      i += 1
+    end
+    ary.compact.size == i
+  end
+  
+  def self.validate_t story
+    Story.serial?(Story.collect_t(story))
+  end
+  
+  def insert_shift
+    Story.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
+  end
+  
+  def lesser_shift old_t
+    self.t = 0 if self.t < 0
+    Story.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, self.t, old_t])
+  end
+  
+  def higher_shift old_t
+    nf = Story.find_t(self.comic_id, self.t)
+    max_t = Story.max_t(self.comic_id).to_i
+    self.t = max_t if self.t > max_t
+    Story.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, old_t, self.t])
+  end
+  
+  def update_shift old_t
+    if self.t > old_t
+      higher_shift old_t
+    else
+      lesser_shift old_t
+    end
+  end
+  
+  def rotate old_t = nil
+    if self.new_record?
+      if self.t.blank?
+        self.t = Story.new_t self.comic_id
+      else
+        self.insert_shift
+      end
+    else
+      if self.t.blank?
+      else
+        self.update_shift old_t
+      end
+    end
+  end
+  
+  def allow? operators
+    return nil if self.story_id == nil or self.comic_id == nil
+    self.comic.own?(operators) and self.comic.usable?(operators)
+  end
+  
+  def store operators, old_t = nil
+    res = false
+    ScrollPanel.transaction do
+      case self.allow? operators
+      when true
+        self.rotate old_t
+      when false
+        raise ActiveRecord::Forbidden
+      else
+      end
+      res = self.save
+      raise ActiveRecord::Rollback unless res
+      res = ScrollPanel.validate_t(self.comic_id) 
+      unless res
+        self.errors.add :t, 'unserialized'
+        raise ActiveRecord::Rollback 
+      end
+    end
+    res
+  end
+  
+end
index b6546da..b90eb91 100644 (file)
@@ -24,9 +24,14 @@ class Folder < Peta::SystemResource
   
   def self.add_local parent, name
     key = parent.name + name + '/'
+    attr = {
+      :name => key, :category_id => 0, :t => 0
+    }
     if i = self.find_by_name(key)
+      i.attributes = attr
+      i.save
     else
-      i = self.create :name => key, :category_id => 0, :t => 0
+      i = self.create attr
     end
     i.move_to_child_of parent
     i
@@ -34,11 +39,16 @@ class Folder < Peta::SystemResource
   
   def self.add_remote parent, name, controller_name = nil, action_name = nil
     key = parent.name + name + '/'
+    attr = {
+      :name => key, :category_id => 10, :t => 0, 
+      :controller_name => (controller_name || name), 
+      :action_name => action_name
+    }
     if i = self.find_by_name(key)
+      i.attributes = attr
+      i.save
     else
-      i = self.create :name => key, :category_id => 10, :t => 0, 
-        :controller_name => (controller_name || name), 
-        :action_name => action_name
+      i = self.create attr
     end
     i.move_to_child_of parent
     i
@@ -87,6 +97,7 @@ class Folder < Peta::SystemResource
     docidx_scroll = self.add_remote docidx, 'scrolls'
     docidx_scroll_panel = self.add_remote docidx, 'scroll_panels'
     docidx_comic = self.add_remote docidx, 'comics'
+    docidx_comic_story = self.add_remote docidx, 'comic_stories'
     docidx_story = self.add_remote docidx, 'stories'
     docidx_story_sheet = self.add_remote docidx, 'story_sheets'
     docidx_sheet = self.add_remote docidx, 'sheets'
@@ -123,6 +134,7 @@ class Folder < Peta::SystemResource
     mydocidx_scroll = self.add_remote mydocidx, 'scrolls'
     mydocidx_scroll_panel = self.add_remote mydocidx, 'scroll_panels'
     mydocidx_comic = self.add_remote mydocidx, 'comics'
+    mydocidx_comic_story = self.add_remote mydocidx, 'comic_stories'
     mydocidx_story = self.add_remote mydocidx, 'stories'
     mydocidx_story_sheet = self.add_remote mydocidx, 'story_sheets'
     mydocidx_sheet = self.add_remote mydocidx, 'sheets'
@@ -140,6 +152,13 @@ class Folder < Peta::SystemResource
     mydocedt_scroll = self.add_remote mydocedt, 'new scroll', 'scrolls', 'new'
     mydocedt_panel = self.add_remote mydocedt, 'new panel', 'panels', 'new'
     mydocedt_original_picture = self.add_remote mydocedt, 'upload picture', 'original_pictures', 'new'
+    # child of /my documents/create/index
+    mydocedtidx = self.add_local mydocedt, 'index'
+    mydocedtidx_scroll = self.add_remote mydocedtidx, 'new scroll', 'scrolls', 'new'
+    mydocedtidx_comic = self.add_remote mydocedtidx, 'new comic', 'comics', 'new'
+    mydocedtidx_story = self.add_remote mydocedtidx, 'new story', 'stories', 'new'
+    mydocedtidx_sheet = self.add_remote mydocedtidx, 'new sheet', 'sheets', 'new'
+    mydocedtidx_panel = self.add_remote mydocedtidx, 'new panel', 'panels', 'new'
     
     # child of /system_resource
     sbt = self.add_remote sr, 'speech_balloon_templates'
index 2d09d53..1410b11 100644 (file)
@@ -1,38 +1,33 @@
 #ストーリー
 class Story < Peta::Binder
   load_manifest
+  has_many :comic_stories
   has_many :story_sheets
-  belongs_to :comic
+  belongs_to :author
   
-  validates :comic_id, :presence => true, :numericality => true, :existence => {:both => false}
   validates :title, :presence => true, :length => {:maximum => 100}
   validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1}
-  validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
+  validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
   
   def supply_default
-    self.comic_id = nil
     self.visible = 0 if self.visible.blank?
-    self.t = nil
   end
   
-  def overwrite
+  def overwrite operators
+    return false unless operators.author
+    self.author_id = operators.author.id
+    super()
   end
   
   def visible? operators
-    return false unless super
-    self.visible > 0
-  end
-  
-  def disp_t
-    self.t + 1
-  end
-  
-  def disp_t_by_text
-    I18n.t('stories.show.t', :t => self.disp_t)
-  end
-  
-  def title_with_t
-    self.disp_t_by_text  + ':' + self.title
+    case super
+    when nil # super return
+      return true
+    when false
+      return false
+    else
+      self.visible > 0
+    end
   end
   
   def story_sheets_count
@@ -48,27 +43,19 @@ class Story < Peta::Binder
   end
   
   def self.list_opt
-    {:comic => {:author => {}} }
-  end
-  
-  def self.by_author_list_includes
-    {
-      :comic => {
-        :author => {}
-      }
-    }
+    {:comic_stories => {:comic => {}}, :author => {} }
   end
   
   def self.list_json_opt
-    {:include => {:comic => {:include => {:author => {}}} }}
+    {:include => {:comic_stories => {:include => {:comic => {}}}, :author => {}}}
   end
   
   def self.show_opt
-    {:include => {:comic => {:author => {}} }}
+    {:include => {:comic_stories => {:comic => {}}, :author => {}}}
   end
   
   def self.show_json_opt
-    {:include => {:comic => {:include => {:author => {}}} }}
+    {:include => {:comic_stories => {:include => {:comic => {}}}, :author => {}}}
   end
   
   def self.visible_count
@@ -87,97 +74,84 @@ class Story < Peta::Binder
     res
   end
   
-  def self.new_t comic_id
-    r = Story.max_t(comic_id)
-    r.blank? ? 0 : r.to_i + 1
+  def parts_element
+    self.leafs_items
   end
   
-  def self.max_t comic_id
-    Story.maximum(:t, :conditions => ['comic_id = ?', comic_id])
+  def zorderd_elements
+    res = []
+    self.parts_element.each do |e|
+      res[e.z-1] = e
+    end
+    res
   end
   
-  def self.find_t comic_id, t
-    Story.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
+  def story_elements
+    res = []
+    self.parts_element.each do |e|
+      res[e.t] = e
+    end
+    res
   end
   
-  def self.collect_t story
-    r = Story.find(:all, :conditions => ['comic_id = ?', story.comic_id], :order => 't')
-    r.map {|s| s.t}
+  def self.collect_element_value elements, name
+    elements.map {|e|
+      if e['_destroy'] or e[:_destroy]
+        nil
+      else
+        e[name]
+      end
+    }
   end
   
-  def self.serial? ary
-    i = 0
-    ary.compact.sort.each do |t|
-      break false unless t == i
+  def self.validate_serial ary, offset = 0
+    i = offset
+    ary.compact.sort.each do |n|
+      break false unless n == i
       i += 1
     end
-    ary.compact.size == i
-  end
-  
-  def self.validate_t story
-    Story.serial?(Story.collect_t(story))
+    ary.compact.size == i - offset
   end
   
-  def insert_shift
-    Story.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
+  def self.validate_element_serial elements, name, offset = 0
+    self.validate_serial(self.collect_element_value(elements, name), offset)
   end
   
-  def lesser_shift old_t
-    self.t = 0 if self.t < 0
-    Story.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, self.t, old_t])
+  def self.validate_elements_serial c
+    c.map {|conf|
+      self.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
+    }.compact.empty?
   end
   
-  def higher_shift old_t
-    nf = Story.find_t(self.comic_id, self.t)
-    max_t = Story.max_t(self.comic_id).to_i
-    self.t = max_t if self.t > max_t
-    Story.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, old_t, self.t])
+  def validate_serial_list
+    [
+      {:elements => self.leafs_items, :name => :t, :offset => 0}, 
+      {:elements => self.leafs_items, :name => :z, :offset => 1}
+    ]
   end
-  
-  def update_shift old_t
-    if self.t > old_t
-      higher_shift old_t
-    else
-      lesser_shift old_t
-    end
+  def validate_child
+#    r1 = Panel.validate_elements_id validate_id_list
+    self.class.validate_elements_serial validate_serial_list
   end
   
-  def rotate old_t = nil
-    if self.new_record?
-      if self.t.blank?
-        self.t = Story.new_t self.comic_id
-      else
-        self.insert_shift
-      end
-    else
-      if self.t.blank?
-      else
-        self.update_shift old_t
-      end
+  def store attr, operators
+    if attr == false
+      self.errors.add :base, I18n.t('errors.invalid_json')
+      return false
     end
-  end
-  
-  def allow? operators
-    return nil if self.comic_id == nil
-    self.comic.own?(operators)
-  end
-  
-  def store operators, old_t = nil
+    self.attributes = attr
+    self.overwrite operators
     res = false
     Story.transaction do
-      case self.allow? operators
-      when true
-        self.rotate old_t
-      when false
-        raise ActiveRecord::Forbidden
-      else
+      self.story_elements.each do |elm|
+        elm.new_story = self
+        elm.boost operators
       end
       res = self.save
-      raise ActiveRecord::Rollback unless res
-      res = Story.validate_t(self) 
-      unless res
-        self.errors.add :t, 'unserialized'
-        raise ActiveRecord::Rollback 
+      unless validate_child
+        res = false
+        self.errors.add :base, I18n.t('errors.invalid_t')
+        raise ActiveRecord::Rollback
       end
     end
     res
diff --git a/app/views/comic_stories/_append_panel.html.erb b/app/views/comic_stories/_append_panel.html.erb
new file mode 100644 (file)
index 0000000..136ac11
--- /dev/null
@@ -0,0 +1,21 @@
+<tr>
+  <td>
+    <%= link_to panel_icon(:object => panel, :size => 25), panel_path(panel) %>
+    <%= link_to author_icon(:object => panel.author, :size => 17), author_path(panel.author) %>
+  </td>
+  <td>
+    <%= link_to h(truncate(h(panel.caption), :length => 40)), panel_path(panel) %>
+  </td>
+  <td>
+    <%= l panel.updated_at %>
+  </td>
+  <td>
+    <% @scroll_panel = ScrollPanel.new :scroll_id => scroll.id, :panel_id => panel.id -%>
+    <%= form_for(@scroll_panel) do |f| %>
+      <%= f.hidden_field :scroll_id %>
+      <%= f.hidden_field :t %>
+      <%= f.hidden_field :panel_id %>
+      <%= f.submit t('scroll_panels.append.panel') %>
+    <% end %>
+  </td>
+</tr>
diff --git a/app/views/comic_stories/_append_scroll.html.erb b/app/views/comic_stories/_append_scroll.html.erb
new file mode 100644 (file)
index 0000000..92be36c
--- /dev/null
@@ -0,0 +1,32 @@
+<tr>
+  <td>
+    <%= link_to scroll_icon(:object => scroll, :size => 25), scroll_path(scroll) %>
+    <%= link_to h(truncate(scroll.title, :length => 40)), play_scroll_path(scroll) %>
+    (<%= scroll.scroll_panels.size -%>)
+  </td>
+  <td>
+    <%= distance_of_time_in_words_to_now scroll.updated_at %>
+  </td>
+  <td>
+    <%= link_to author_icon(:object => scroll.author, :size => 25), author_path(scroll.author) %>
+    <%= link_to h(truncate(scroll.author.name, :length => 12)), author_path(scroll.author) %>
+  </td>
+  <td>
+    <% if scroll.own? operators %>
+      <% @scroll_panel = ScrollPanel.new :scroll_id => scroll.id, :panel_id => panel.id %>
+      <%= form_for(@scroll_panel) do |f| %>
+        <%= f.hidden_field :scroll_id %>
+        <%= f.hidden_field :t %>
+        <%= f.hidden_field :panel_id %>
+        <div class="actions">
+          <%= f.submit t('scroll_panels.append.scroll') %>
+        </div>
+      <% end %>
+    <% end %>
+  </td>
+</tr>
+<tr>
+  <td colspan="4">
+    <%= h(truncate(scroll.description, :length => 40)) %>
+  </td>
+</tr>
diff --git a/app/views/comic_stories/_footer.html.erb b/app/views/comic_stories/_footer.html.erb
new file mode 100644 (file)
index 0000000..69c5438
--- /dev/null
@@ -0,0 +1,23 @@
+<table class="no-border" style="margin: 0px; padding: 0px; width=100%">
+  <tr>
+    <td>
+      <% if scroll_panel.panel -%>
+        <%= link_to panel_icon(:object => scroll_panel.panel, :size => 25), panel_path(scroll_panel.panel) %>
+        <%= link_to author_icon(:object => scroll_panel.panel.author, :size => 17), author_path(scroll_panel.panel.author) %>
+        <%= distance_of_time_in_words_to_now scroll_panel.panel.updated_at %>
+      <% end %>
+    </td>
+    <td>
+      <%= link_to scroll_panel_icon(:object => scroll_panel, :size => 25), scroll_panel_path(scroll_panel) %>
+      <%= link_to author_icon(:object => scroll_panel.author, :size => 17), author_path(scroll_panel.author) %>
+      <%= l scroll_panel.updated_at %>
+    </td>
+    <td>
+      <% if scroll_panel.own? operators %>
+        <%= render 'scroll_panels/order', :scroll_panel => scroll_panel %>
+      <% else %>
+        No.<%= scroll_panel.t %>
+      <% end %>
+    </td>
+  </tr>
+</table>
diff --git a/app/views/comic_stories/_form.html.erb b/app/views/comic_stories/_form.html.erb
new file mode 100644 (file)
index 0000000..0cf77a8
--- /dev/null
@@ -0,0 +1,26 @@
+<%= form_for(@scroll_panel) do |f| %>
+  <%= render 'system/error_explanation', :obj => @scroll_panel %>
+
+  <div class="field">
+    <%= f.label :scroll_id %><br />
+    <%= f.number_field :scroll_id %>
+  </div>
+  <div class="row_break">
+  </div>
+  <div class="field">
+    <%= f.label :t %><br />
+    <%= f.number_field :t %>
+  </div>
+  <div class="row_break">
+  </div>
+  <div class="field">
+    <%= f.label :panel_id %><br />
+    <%= f.number_field :panel_id %>
+  </div>
+  <div class="row_break">
+  </div>
+
+  <div class="actions">
+    <%= f.submit %>
+  </div>
+<% end %>
diff --git a/app/views/comic_stories/_licensed_pictures.html.erb b/app/views/comic_stories/_licensed_pictures.html.erb
new file mode 100644 (file)
index 0000000..1c10cc7
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="pettanr-licensed_pictures">
+  <% licensed_pictures.each do |pid, picture| %>
+    <table class="no-border">
+      <tr>
+        <td>
+          <%= link_to(tag(:img, picture.tmb_opt_img_tag), picture_path(picture.id)) -%>
+        </td>
+        <td>
+          <%= render picture.credit_template, :picture => picture %>
+        </td>
+      </tr>
+    </table>
+  <% end %>
+</div>
diff --git a/app/views/comic_stories/_order.html.erb b/app/views/comic_stories/_order.html.erb
new file mode 100644 (file)
index 0000000..6d515f8
--- /dev/null
@@ -0,0 +1,15 @@
+<%= form_for(scroll_panel) do |f| %>
+  <table class="no-border">
+    <tr>
+      <td>
+        No.
+        <%= f.number_field :t, :size => 3 %>
+        <%= f.hidden_field :panel_id %>
+        <%= f.hidden_field :scroll_id %>
+      </td>
+      <td>
+        <%= f.submit t 'scroll_panels.move' %>
+      </td>
+    </tr>
+  </table>
+<% end %>
diff --git a/app/views/comic_stories/_scroll_header.html.erb b/app/views/comic_stories/_scroll_header.html.erb
new file mode 100644 (file)
index 0000000..df0997b
--- /dev/null
@@ -0,0 +1,40 @@
+<h1>
+  <%= link_to scroll_icon, scroll_path(scroll) %>
+  <%= link_to h(scroll.title), play_scroll_path(scroll) %>
+</h1>
+<% if scroll.own? operators -%>
+  <%= form_for(scroll) do |f| %>
+    <div class="field">
+      <%= f.label :title %><br />
+      <%= f.text_field :title %>
+    </div>
+    <div class="field">
+      <%= f.label :visible %><br />
+      <%= f.collection_select :visible, t_select_items(manifest.system_resources.select_items['scroll_visible_items']), :last, :first, :html => {:selected => @scroll.visible} %>
+    </div>
+    <div class="actions">
+      <%= f.submit %>
+    </div>
+  <% end %>
+<% else %>
+  <p>
+    <b><%= t_m 'Scroll.visible' -%>:</b>
+    <%= t_selected_item('scroll_visible_items', @scroll.visible) %>
+  </p>
+<% end %>
+
+<p>
+  <b><%= t_m 'Scroll.author_id' -%>:</b>
+  <%= link_to h(@scroll.author.name), author_path(@scroll.author) %>
+</p>
+
+<p>
+  <b><%= t_m 'Scroll.created_at' -%>:</b>
+  <%= l @scroll.created_at %>
+</p>
+
+<p>
+  <b><%= t_m 'Scroll.updated_at' -%>:</b>
+  <%= l @scroll.updated_at %>
+</p>
+
diff --git a/app/views/comic_stories/_summary.html.erb b/app/views/comic_stories/_summary.html.erb
new file mode 100644 (file)
index 0000000..59204fb
--- /dev/null
@@ -0,0 +1,9 @@
+<div>
+  <%= link_to comic_icon(:object => item.comic, :size => 32), comic_path(item.comic) %>
+  <% if item.story %>
+    <%= link_to story_icon(:object => item.story, :size => 32), story_path(item.story) %>
+  <% end %>
+</div>
+<div>
+  <%= link_to h(truncate(item.comic.author.name, :length => 12)), author_path(item.comic.author) %>
+</div>
diff --git a/app/views/comic_stories/edit.html.erb b/app/views/comic_stories/edit.html.erb
new file mode 100644 (file)
index 0000000..1d67f75
--- /dev/null
@@ -0,0 +1,4 @@
+<h1><%= t('.title') %></h1>
+<p id="notice"><%= notice %></p>
+
+<%= render 'form' %>
diff --git a/app/views/comic_stories/new.html.erb b/app/views/comic_stories/new.html.erb
new file mode 100644 (file)
index 0000000..f33a2f8
--- /dev/null
@@ -0,0 +1,3 @@
+<h1><%= t('.title') %></h1>
+
+<%= render 'form' %>
index 4911dee..b851de5 100644 (file)
@@ -1,6 +1,6 @@
 <div>
   <%= t_selected_item('comic_visible_items', item.visible) %>
-  <%= t('comics.comic_stories_count', :c => item.comic_stories_count) %>
+  <%= t('comics.comic_stories_count', :c => item.comic_stories.count) %>
 </div>
 <div>
   <%= link_to h(truncate(item.author.name, :length => 12)), author_path(item.author) %>
index 9d05abc..940683c 100644 (file)
@@ -1,8 +1,6 @@
 <div>
   <%= t_selected_item('story_visible_items', item.visible) %>
-  <%= t('stories.story_sheets_count', :c => item.story_sheets_count) %>
-  <%= link_to h(item.comic.title), comic_path(item.comic) %>
 </div>
 <div>
-  <%= link_to h(truncate(item.comic.author.name, :length => 12)), author_path(item.comic.author) %>
+  <%= link_to h(truncate(item.author.name, :length => 12)), author_path(item.author) %>
 </div>
index 6f9cc26..8892ded 100644 (file)
@@ -1,14 +1,8 @@
 <h1><%= t('.title') %></h1>
 <p id="notice"><%= notice %></p>
 
-<p>
-  <b><%= t_m 'Story.comic_id' -%>:</b>
-  <%= link_to comic_icon(:object => @item.comic), comic_path(@item.comic) %>
-  <%= link_to h(@item.comic.title), comic_path(@item.comic) %>
-</p>
-
 <div>
-  <%= link_to t('stories.show.t', :t => @item.disp_t), story_path(@item) %>
+  <%= link_to @item.title, story_path(@item) %>
   <%= link_to_if @item, h(@item.title), play_story_path(@item) %>
 </div>
 
index 92befec..67bb4b4 100644 (file)
@@ -22,6 +22,7 @@ ja:
       scroll: スクロール
       scroll_panel: スクコマ
       comic: コミック
+      comic_story: コミスト
       story: ストーリー
       story_sheet: スト紙
       sheet: 用紙
@@ -98,7 +99,6 @@ ja:
       scroll_panel:
         scroll_id: スクロール
         panel_id: コマ
-        author_id: 編集者
         t: No.
         created_at: 作成
         updated_at: 更新
@@ -109,6 +109,12 @@ ja:
         author_id: 作家
         created_at: 更新
         updated_at: 作成
+      comic_story:
+        comic_id: コミック
+        story_id: ストーリー
+        t: No.
+        created_at: 作成
+        updated_at: 更新
       story:
         comic_id: コミック
         title: タイトル
@@ -121,7 +127,6 @@ ja:
       story_sheet:
         story_id: ストーリー
         sheet_id: 用紙
-        author_id: 編集者
         t: No.
         created_at: 作成
         updated_at: 更新
@@ -636,6 +641,8 @@ ja:
       title: 最近更新したスクコマ
     comics:
       title: 最近更新したコミック
+    comic_stories:
+      title: 最近更新したコミスト
     stories:
       title: 最近更新したストーリー
     story_sheets:
@@ -787,6 +794,37 @@ ja:
     submit:
       new: コミック作成
       edit: コミック変更
+  comic_stories:
+    index:
+      title: コミスト一覧
+    by_comic:
+      title: コミックのコミスト一覧
+    by_story:
+      title: ストーリーのコミスト一覧
+    by_author:
+      title: 作家のコミスト一覧
+    show:
+      title: コミスト詳細
+    new:
+      title: コミスト追加
+    edit:
+      title: 並び替え
+    create:
+      title: コミスト追加
+    update:
+      title: 並び替え
+    destroy:
+      title: コミスト削除
+    submit:
+      new: コミスト作成
+      edit: コミスト変更
+    move: 移動
+    append:
+      story: このストーリーを追加する
+      comic: このコミックに追加する
+      new_stories: 最近作成したストーリー
+      new_comics: 最近作成したコミック
+      fresh_comics: 最近更新したコミック
   stories:
     story_sheets_count: '%{c}P'
     index:
@@ -1236,6 +1274,7 @@ ja:
       to_scrolls: 最近更新したスクロール
       to_scroll_panels: 最近更新したスクコマ
       to_comics: 最近更新したコミック
+      to_comic_stories: 最近更新したコミスト
       to_stories: 最近更新したストーリー
       to_story_sheets: 最近更新したスト紙
       to_sheets: 最近更新した用紙
index 6299c42..a6af26d 100644 (file)
@@ -40,12 +40,8 @@ Pettanr::Application.routes.draw do
       post :create
     end
     member do
-      get :scroll_panels
-      get :panels
       get :by_author
       get :by_panel
-      get :scroll_panels_count
-      get :panels_count
       get :count_by_author
       get :count_by_panel
       get :play
@@ -62,6 +58,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -87,18 +84,38 @@ Pettanr::Application.routes.draw do
       post :create
     end
     member do
-      get :stories
       get :by_author
-      get :by_me
-      get :stories_count
+      get :by_story
       get :count_by_author
-      get :count_by_me
+      get :count_by_story
       get :play
       get :edit
       put :update
       delete :destroy
     end
   end
+  resources :comic_stories do
+    new do
+      get :new
+    end
+    collection do
+      get :index
+      get :show
+      get :count
+      post :create
+    end
+    member do
+      get :by_comic
+      get :by_story
+      get :by_author
+      get :count_by_comic
+      get :count_by_story
+      get :count_by_author
+      get :edit
+      put :update
+      delete :destroy
+    end
+  end
   resources :stories do
     new do
       get :new
@@ -106,16 +123,13 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
-      get :story_sheets
-      get :sheets
       get :by_comic
       get :by_sheet
       get :by_author
-      get :story_sheets_count
-      get :sheets_count
       get :count_by_comic
       get :count_by_sheet
       get :count_by_author
@@ -132,6 +146,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -184,6 +199,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -244,6 +260,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -263,6 +280,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -280,6 +298,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :by_speech_balloon
@@ -293,6 +312,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :by_speech_balloon
@@ -310,6 +330,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :by_panel
@@ -328,6 +349,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :by_panel
@@ -346,6 +368,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       post :create
     end
     member do
@@ -359,6 +382,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       get :credit
       get :search
       get :list
@@ -372,6 +396,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
       get :new
       post :create
       get :count
@@ -391,6 +416,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :speech_balloons
@@ -406,6 +432,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :speeches
@@ -418,6 +445,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       get :licenses
@@ -455,6 +483,7 @@ Pettanr::Application.routes.draw do
       get :scrolls
       get :scroll_panels
       get :comics
+      get :comic_stories
       get :stories
       get :story_sheets
       get :sheets
@@ -503,6 +532,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :count
     end
     member do
       #get :balloons
diff --git a/db/migrate/20140519235843_create_comic_stories.rb b/db/migrate/20140519235843_create_comic_stories.rb
new file mode 100644 (file)
index 0000000..0e47deb
--- /dev/null
@@ -0,0 +1,12 @@
+class CreateComicStories < ActiveRecord::Migration
+  def change
+    create_table :comic_stories do |t|
+      t.integer :comic_id, :null => false, :default => 0
+      t.integer :story_id, :null => false, :default => 0
+      t.integer :author_id, :null => false, :default => 0
+      t.integer :t, :null => false, :default => 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20140520102407_rm_comic_id_on_story.rb b/db/migrate/20140520102407_rm_comic_id_on_story.rb
new file mode 100644 (file)
index 0000000..fc52a7b
--- /dev/null
@@ -0,0 +1,17 @@
+class RmComicIdOnStory < ActiveRecord::Migration
+  def up
+    add_column :stories, :author_id, :integer, :null => false, :default => 0
+    Story.all.each do |s|
+      c = Comic.find(s.comic_id)
+      ComicStory.create! :comic_id => s.comic_id, :story_id => s.id,
+        :author_id => c.author_id, :t => s.t
+      s.author_id = c.author_id
+      s.save!
+    end
+    remove_column :stories, :comic_id
+    remove_column :stories, :t
+  end
+
+  def down
+  end
+end
diff --git a/public/images/comic_story.gif b/public/images/comic_story.gif
new file mode 100644 (file)
index 0000000..0707502
Binary files /dev/null and b/public/images/comic_story.gif differ
index aac9867..6234fef 100644 (file)
         },\r
         "by_author": {\r
           "type": "filter"\r
+        },\r
+        "by_story": {\r
+          "type": "through_filter",\r
+          "args": {\r
+            "through": "comic_stories"\r
+          }\r
         }\r
       }\r
     },\r
-    "story": {\r
+    "comic_story": {\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
         "private": {\r
           "type": "private"\r
         },\r
+        "play": {\r
+          "type": "play",\r
+          "args": {\r
+            "filter_item_name": "comic",\r
+            "filter_model_name": "comic_story",\r
+            "filter_key": "comic_id"\r
+          }\r
+        },\r
         "by_comic": {\r
           "type": "filter"\r
         },\r
-        "by_sheet": {\r
-          "type": "through_filter",\r
-          "args": {\r
-            "through": "story_sheets"\r
-          }\r
+        "by_story": {\r
+          "type": "filter"\r
         },\r
         "by_author": {\r
           "type": "foreign_filter",\r
               "type": "method"\r
             }\r
           }\r
+        }\r
+      }\r
+    },\r
+    "story": {\r
+      "lists": {\r
+        "public": {\r
+          "type": "public"\r
         },\r
-        "play": {\r
-          "type": "play"\r
+        "private": {\r
+          "type": "private"\r
+        },\r
+        "by_comic": {\r
+          "type": "through_filter",\r
+          "args": {\r
+            "through": "comic_stories"\r
+          }\r
+        },\r
+        "by_sheet": {\r
+          "type": "through_filter",\r
+          "args": {\r
+            "through": "story_sheets"\r
+          }\r
+        },\r
+        "by_author": {\r
+          "type": "filter"\r
         }\r
       }\r
     },\r
           "author"\r
         ],\r
         "has_many": [\r
+          "comic_stories.by_comic",\r
           "stories.by_comic"\r
         ]\r
       }\r
     },\r
-    "story": {\r
+    "comic_story": {\r
       "column_names": [\r
         "comic_id",\r
+        "story_id",\r
+        "t"\r
+      ],\r
+      "associations": {\r
+        "belongs_to": [\r
+          "comic",\r
+          "story"\r
+        ]\r
+      }\r
+    },\r
+    "story": {\r
+      "column_names": [\r
         "title",\r
         "description",\r
         "t",\r
         "visible"\r
       ],\r
       "associations": {\r
-        "belongs_to": [\r
-          "comic"\r
-        ],\r
+        "belongs_to": [],\r
         "has_many": [\r
+          "comic_stories.by_story",\r
+          "comics.by_story",\r
           "story_sheets.by_story",\r
           "sheets.by_story"\r
         ]\r
           "scrolls.by_author",\r
           "scroll_panels.by_author",\r
           "comics.by_author",\r
+          "comic_stories.by_author",\r
           "stories.by_author",\r
           "sheets.by_author",\r
           "sheet_panels.by_author",\r
       "summary": {},\r
       "edit": {}\r
     },\r
+    "comic_story": {\r
+      "symbol": {\r
+        "type": "default",\r
+        "args": {\r
+          "link": {\r
+            "type": "none"\r
+          }\r
+        }\r
+      },\r
+      "caption": {\r
+        "type": "none"\r
+      },\r
+      "summary": {},\r
+      "edit": {\r
+        "type": "none"\r
+      }\r
+    },\r
     "story": {\r
       "symbol": {},\r
       "caption": {\r
         "type": "default",\r
         "args": {\r
           "face": {\r
-            "type": "method",\r
+            "type": "column",\r
             "args": {\r
-              "method_name": "title_with_t"\r
+              "column_name": "title"\r
             }\r
           },\r
           "link": {\r
         "author_id"\r
       ]\r
     },\r
-    "story": {\r
+    "comic_story": {\r
       "fields": {\r
         "comic_id": {\r
+          "tag": {\r
+            "type": "number"\r
+          }\r
+        },\r
+        "story_id": {\r
+          "tag": {\r
+            "type": "number"\r
+          }\r
+        },\r
+        "t": {\r
+          "tag": {\r
+            "type": "number"\r
+          }\r
+        },\r
+        "id": {\r
           "label": {\r
             "type": "none"\r
           },\r
           "tag": {\r
             "type": "hidden"\r
           }\r
-        },\r
+        }\r
+      },\r
+      "field_names": [\r
+        "comic_id",\r
+        "story_id",\r
+        "t",\r
+        "id"\r
+      ]\r
+    },\r
+    "story": {\r
+      "fields": {\r
         "title": {\r
           "label": {\r
             "args": {\r
           },\r
           "row_break": true\r
         },\r
-        "t": {\r
-          "tag": {\r
-            "type": "number"\r
-          }\r
-        },\r
         "id": {\r
           "label": {\r
             "type": "none"\r
         }\r
       },\r
       "field_names": [\r
-        "comic_id",\r
         "title",\r
         "description",\r
         "visible",\r
-        "t",\r
         "id",\r
         "author_id"\r
       ]\r
index 2d94439..87677ac 100644 (file)
       "type": "binder",\r
       "args": {}\r
     },\r
+    "comic_story": {\r
+      "type": "leaf",\r
+      "args": {\r
+        "parent_model_name": "comic"\r
+      }\r
+    },\r
     "story": {\r
       "type": "binder",\r
       "args": {}\r
             "list_name": "public"\r
           }\r
         },\r
+        "by_story": {\r
+          "type": "list"\r
+        },\r
         "by_author": {\r
           "type": "list"\r
         },\r
             "list_name": "public"\r
           }\r
         },\r
+        "count_by_story": {\r
+          "type": "count"\r
+        },\r
         "count_by_author": {\r
           "type": "count"\r
         },\r
         }\r
       }\r
     },\r
-    "stories": {\r
+    "comic_stories": {\r
       "actions": {\r
         "index": {\r
           "type": "list",\r
           }\r
         },\r
         "by_comic": {\r
+          "type": "list"\r
+        },\r
+        "by_story": {\r
+          "type": "list"\r
+        },\r
+        "by_author": {\r
+          "type": "list"\r
+        },\r
+        "show": {\r
+          "type": "show"\r
+        },\r
+        "count": {\r
+          "type": "count",\r
+          "args": {\r
+            "list_name": "public"\r
+          }\r
+        },\r
+        "count_by_comic": {\r
           "type": "count"\r
         },\r
-        "by_sheet": {\r
+        "count_by_story": {\r
+          "type": "count"\r
+        },\r
+        "count_by_author": {\r
           "type": "count"\r
         },\r
+        "new": {\r
+          "type": "new"\r
+        },\r
+        "edit": {\r
+          "type": "edit"\r
+        }\r
+      }\r
+    },\r
+    "stories": {\r
+      "actions": {\r
+        "index": {\r
+          "type": "list",\r
+          "args": {\r
+            "list_name": "public"\r
+          }\r
+        },\r
+        "by_comic": {\r
+          "type": "list"\r
+        },\r
+        "by_sheet": {\r
+          "type": "list"\r
+        },\r
         "by_author": {\r
           "type": "list"\r
         },\r
             "list_name": "public"\r
           }\r
         },\r
+        "count_by_comic": {\r
+          "type": "count"\r
+        },\r
+        "count_by_sheet": {\r
+          "type": "count"\r
+        },\r
         "count_by_author": {\r
           "type": "count"\r
         },\r
         "has_many": {\r
           "scroll_panels": {},\r
           "panels": {\r
-            "through": "scroll_panel"\r
+            "through": "scroll_panels"\r
           }\r
         }\r
       },\r
           "author": {}\r
         },\r
         "has_many": {\r
-          "stories": {}\r
+          "comic_stories": {},\r
+          "stories": {\r
+            "through": "comic_stories"\r
+          }\r
         }\r
       },\r
       "attributes": {\r
         }\r
       }\r
     },\r
-    "story": {\r
+    "comic_story": {\r
       "associations": {\r
         "belongs_to": {\r
-          "comic": {}\r
+          "comic": {},\r
+          "story": {}\r
         },\r
-        "has_many": {\r
-          "story_sheets": {},\r
-          "sheets": {\r
-            "through": "story_sheets"\r
-          }\r
-        }\r
+        "has_many": {}\r
       },\r
       "attributes": {\r
         "comic_id": {\r
           "type": "number",\r
           "rules": {\r
+            "required": true,\r
             "number": true\r
           }\r
         },\r
+        "story_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        },\r
+        "t": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true,\r
+            "min": 0\r
+          }\r
+        },\r
+        "author_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "story": {\r
+      "associations": {\r
+        "belongs_to": {},\r
+        "has_many": {\r
+          "comic_stories": {},\r
+          "comics": {\r
+            "through": "comic_stories"\r
+          },\r
+          "story_sheets": {},\r
+          "sheets": {\r
+            "through": "story_sheets"\r
+          }\r
+        }\r
+      },\r
+      "attributes": {\r
         "title": {\r
           "type": "text",\r
           "rules": {}\r
               "select_item_name": "story_visible_items"\r
             }\r
           }\r
+        },\r
+        "author_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
         }\r
       }\r
     },\r
diff --git a/spec/controllers/comic_stories_controller_spec.rb b/spec/controllers/comic_stories_controller_spec.rb
new file mode 100644 (file)
index 0000000..9d81946
--- /dev/null
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe ComicStoriesController do
+
+end
diff --git a/spec/helpers/comic_stories_helper_spec.rb b/spec/helpers/comic_stories_helper_spec.rb
new file mode 100644 (file)
index 0000000..06dbc6c
--- /dev/null
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ComicStoriesHelper. For example:
+#
+# describe ComicStoriesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe ComicStoriesHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/comic_story_spec.rb b/spec/models/comic_story_spec.rb
new file mode 100644 (file)
index 0000000..9ec5a24
--- /dev/null
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe ComicStory do
+  pending "add some examples to (or delete) #{__FILE__}"
+end