OSDN Git Service

fix extend
authoryasushiito <yas@pen-chan.jp>
Mon, 31 Mar 2014 22:23:47 +0000 (07:23 +0900)
committeryasushiito <yas@pen-chan.jp>
Mon, 31 Mar 2014 22:23:47 +0000 (07:23 +0900)
25 files changed:
app/assets/javascripts/manifest/work/forms.js.coffee.erb
app/assets/javascripts/manifest/work/items.js.coffee.erb
app/assets/javascripts/manifest/work/models.js.coffee.erb
app/assets/javascripts/manifest/work/profilers.js.coffee.erb
app/models/balloon.rb
app/models/license.rb
app/models/speech.rb
app/models/speech_balloon.rb
config/environment.rb
config/locales/pettanr.ja.yml
db/migrate/20140329220907_fix_extend_system.rb
db/migrate/20140329222717_fix_extend_system_data.rb
lib/locmare/booster.rb [new file with mode: 0644]
lib/locmare/profiler.rb
lib/locmare/profiler/column.rb
lib/manifest/item/base.rb
lib/manifest/item/boost.rb
lib/manifest/manifest.rb
lib/peta/element.rb
lib/peta/item.rb
lib/peta/leaf.rb
lib/validators/extend_balloon_validator.rb
lib/validators/extend_speech_validator.rb
public/local_manifest.json
public/manifest.json

index 5765616..8fafe2c 100644 (file)
             },\r
           },\r
         },\r
-        'speech_balloon.classname': {\r
+        'speech_balloon.speech_balloon_template_classname': {\r
           args: {\r
             label: {\r
               type: 'none',\r
             },\r
           },\r
         },\r
-        'speech_balloon.settings': {\r
+        'speech_balloon.speech_balloon_template_settings': {\r
           args: {\r
             label: {\r
               type: 'none',\r
             },\r
           },\r
         },\r
+        'balloon.speech_balloon_template_id': {\r
+          type: 'part',\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
         'balloon.system_picture_id': {\r
           type: 'part',\r
           args: {\r
             row_break: true,\r
           },\r
         },\r
-        'balloon.settings': {\r
+        'balloon.speech_balloon_template_classname': {\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
+        'balloon.speech_balloon_template_settings': {\r
           type: 'part',\r
           args: {\r
             label: {\r
             },\r
           },\r
         },\r
+        'speech.speech_balloon_template_id': {\r
+          type: 'part',\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
         'speech.x': {\r
           type: 'part',\r
           args: {\r
             },\r
           },\r
         },\r
-        'speech.settings': {\r
+        'speech.speech_balloon_template_classname': {\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
+        'speech.writing_format_classname': {\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
+        'speech.speech_balloon_template_settings': {\r
+          type: 'part',\r
+          args: {\r
+            label: {\r
+              type: 'none',\r
+            },\r
+            tag: {\r
+              type: 'hidden',\r
+            },\r
+          },\r
+        },\r
+        'speech.writing_format_settings': {\r
           type: 'part',\r
           args: {\r
             label: {\r
         'balloon.id',\r
         'balloon.speech_balloon_id',\r
         'balloon.system_picture_id',\r
-        'balloon.settings',\r
+        'balloon.speech_balloon_template_id',\r
+        'balloon.speech_balloon_template_classname',\r
+        'balloon.speech_balloon_template_settings',\r
         'speech.writing_format_id',\r
         'speech.font_size',\r
         'speech.text_align',\r
         'speech.y',\r
         'speech.width',\r
         'speech.height',\r
-        'speech.settings',\r
+        'speech.speech_balloon_template_id',\r
+        'speech.speech_balloon_template_classname',\r
+        'speech.speech_balloon_template_settings',\r
+        'speech.writing_format_classname',\r
+        'speech.writing_format_settings',\r
         'speech_balloon.id',\r
         'speech_balloon.panel_id',\r
         'speech_balloon.speech_balloon_template_id',\r
-        'speech_balloon.classname',\r
+        'speech_balloon.speech_balloon_template_classname',\r
         'speech_balloon.z',\r
         'speech_balloon.t',\r
-        'speech_balloon.settings',\r
+        'speech_balloon.speech_balloon_template_settings',\r
       ]\r
     },\r
     PlainSpeechBalloon: {\r
         'balloon.id',\r
         'balloon.speech_balloon_id',\r
         'balloon.system_picture_id',\r
-        'balloon.settings',\r
+        'balloon.speech_balloon_template_id',\r
+        'balloon.speech_balloon_template_classname',\r
+        'balloon.speech_balloon_template_settings',\r
         'speech.writing_format_id',\r
         'speech.font_size',\r
         'speech.text_align',\r
         'speech.y',\r
         'speech.width',\r
         'speech.height',\r
-        'speech.settings',\r
+        'speech.speech_balloon_template_id',\r
+        'speech.speech_balloon_template_classname',\r
+        'speech.speech_balloon_template_settings',\r
+        'speech.writing_format_classname',\r
+        'speech.writing_format_settings',\r
         'speech_balloon.id',\r
         'speech_balloon.panel_id',\r
         'speech_balloon.speech_balloon_template_id',\r
-        'speech_balloon.classname',\r
+        'speech_balloon.speech_balloon_template_classname',\r
         'speech_balloon.z',\r
         'speech_balloon.t',\r
-        'speech_balloon.settings',\r
+        'speech_balloon.speech_balloon_template_settings',\r
       ]\r
     },\r
     SquareSpeechBalloon: {\r
         'balloon.id',\r
         'balloon.speech_balloon_id',\r
         'balloon.system_picture_id',\r
-        'balloon.settings',\r
+        'balloon.speech_balloon_template_id',\r
+        'balloon.speech_balloon_template_classname',\r
+        'balloon.speech_balloon_template_settings',\r
         'speech.writing_format_id',\r
         'speech.font_size',\r
         'speech.text_align',\r
         'speech.y',\r
         'speech.width',\r
         'speech.height',\r
-        'speech.settings',\r
+        'speech.speech_balloon_template_id',\r
+        'speech.speech_balloon_template_classname',\r
+        'speech.speech_balloon_template_settings',\r
+        'speech.writing_format_classname',\r
+        'speech.writing_format_settings',\r
         'speech_balloon.id',\r
         'speech_balloon.panel_id',\r
         'speech_balloon.speech_balloon_template_id',\r
-        'speech_balloon.classname',\r
+        'speech_balloon.speech_balloon_template_classname',\r
         'speech_balloon.z',\r
         'speech_balloon.t',\r
-        'speech_balloon.settings',\r
+        'speech_balloon.speech_balloon_template_settings',\r
       ]\r
     },\r
   }\r
index eceb164..f8cc392 100644 (file)
@@ -55,6 +55,8 @@
       parent_model_name: 'panel',\r
       boost: {\r
         speech_balloon_template: {\r
+          setter_method_name: 'extend_speech_balloon=',\r
+          getter_method_name: 'extend_speech_balloon',\r
         },\r
       },\r
     },\r
@@ -65,6 +67,8 @@
       parent_model_name: 'speech_balloon',\r
       boost: {\r
         speech_balloon_template: {\r
+          setter_method_name: 'extend_balloon=',\r
+          getter_method_name: 'extend_balloon',\r
         },\r
       },\r
     },\r
@@ -77,6 +81,8 @@
         writing_format: {\r
         },\r
         speech_balloon_template: {\r
+          setter_method_name: 'extend_speech=',\r
+          getter_method_name: 'extend_speech',\r
         },\r
       },\r
     },\r
       parent_model_name: 'license_group',\r
       boost: {\r
         license_group: {\r
+          extend_item_name: 'attribute',\r
         },\r
       },\r
     },\r
index 591ffc6..5858dbd 100644 (file)
           number: true,\r
         }\r
       },\r
-      classname: {\r
+      speech_balloon_template_classname: {\r
         type: 'text',\r
         rules : {\r
           required: true,\r
           min: 0,\r
         }\r
       },\r
-      settings: {\r
+      speech_balloon_template_settings: {\r
         type: 'text',\r
         rules : {\r
         }\r
           number: true,\r
         }\r
       },\r
+      speech_balloon_template_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+      speech_balloon_template_classname: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
       system_picture_id: {\r
         type: 'number',\r
         rules : {\r
           number: true,\r
         }\r
       },\r
-      settings: {\r
+      speech_balloon_template_settings: {\r
         type: 'text',\r
         rules : {\r
         }\r
           number: true,\r
         }\r
       },\r
+      speech_balloon_template_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+      speech_balloon_template_classname: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
       writing_format_id: {\r
         type: 'number',\r
         source: {\r
           number: true,\r
         }\r
       },\r
+      writing_format_classname: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
       content: {\r
         type: 'text',\r
         rules : {\r
         rules : {\r
         }\r
       },\r
-      settings: {\r
+      speech_balloon_template_settings: {\r
+        type: 'text',\r
+        rules : {\r
+        }\r
+      },\r
+      writing_format_settings: {\r
         type: 'text',\r
         rules : {\r
         }\r
           number: true,\r
         }\r
       },\r
+      license_group_classname: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
       name: {\r
         type: 'text',\r
         rules : {\r
           required: true,\r
         }\r
       },\r
-      settings: {\r
+      license_group_settings: {\r
         type: 'text',\r
         rules : {\r
         }\r
       },\r
     },\r
   },\r
+  ###############################################################\r
+  #\r
+  # extend models\r
+  #\r
+  ################################################################\r
+  circle_speech_balloon_speech_balloon: {\r
+    attributes: {\r
+      width: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+    },\r
+  },\r
+  circle_speech_balloon_speech_balloon: {\r
+    attributes: {\r
+      width: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+    },\r
+  },\r
+  circle_speech_balloon_speech_balloon: {\r
+    attributes: {\r
+      width: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+    },\r
+  },\r
+  pettanr_pettan_commons_v01_licenses_attribute: {\r
+    attributes: {\r
+      license_id: {\r
+        type: 'number',\r
+        rules : {\r
+          required: true,\r
+          number: true,\r
+        }\r
+      },\r
+      artist_name: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
+      caption: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
+      sources: {\r
+        type: 'text',\r
+        rules : {\r
+          required: true,\r
+        }\r
+      },\r
+    },\r
+  },\r
 }\r
 \r
index d8c63d8..24fbd52 100644 (file)
     }, \r
   },\r
   speech_balloon: {\r
+    columns: {\r
+      speech_balloon_template_settings: {\r
+        type: 'extend',\r
+      }, \r
+    },\r
     column_names: [\r
       'panel_id', \r
+      'caption', \r
       'speech_balloon_template_id', \r
-      'classname', \r
+      'speech_balloon_template_classname', \r
       'z', \r
       't', \r
-      'settings', \r
-      'caption', \r
+      'speech_balloon_template_settings'\r
     ],\r
     associations: {\r
       belongs_to: [\r
     }, \r
   },\r
   speech: {\r
+    columns: {\r
+      speech_balloon_template_settings: {\r
+        type: 'extend',\r
+      }, \r
+    },\r
     column_names: [\r
       'speech_balloon_id', \r
+      'speech_balloon_template_id', \r
+      'speech_balloon_template_classname', \r
       'writing_format_id', \r
+      'writing_format_classname', \r
       'content', \r
       'font_size', \r
       'text_align', \r
       'width', \r
       'height', \r
       'quotes', \r
-      'settings', \r
+      'speech_balloon_template_settings', \r
+      'writing_format_settings', \r
     ],\r
     associations: {\r
       belongs_to: [\r
     }, \r
   },\r
   balloon: {\r
+    columns: {\r
+      speech_balloon_template_settings: {\r
+        type: 'extend',\r
+      }, \r
+    },\r
     column_names: [\r
       'speech_balloon_id', \r
+      'speech_balloon_template_id', \r
+      'speech_balloon_template_classname', \r
       'system_picture_id', \r
       'x', \r
       'y', \r
       'width', \r
       'height', \r
       'r', \r
-      'settings', \r
+      'speech_balloon_template_settings', \r
     ],\r
     associations: {\r
       belongs_to: [\r
       'system_picture_id', \r
       'settings', \r
     ],\r
+    extend_settings: {\r
+      circle_speech_balloon_speech_balloon: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+      circle_speech_balloon_balloon: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+      circle_speech_balloon_speech: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+      plain_speech_balloon_speech_balloon: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+      square_speech_balloon_speech_balloon: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+    }, \r
     associations: {\r
       belongs_to: [\r
         'system_picture',\r
       'system_picture_id', \r
       'settings', \r
     ],\r
+    extend_settings: {\r
+      pettanr_simple_format_writing_format: {\r
+        columns: {\r
+        },\r
+        column_names: [\r
+        ],\r
+      },\r
+    }, \r
     associations: {\r
       belongs_to: [\r
         'system_picture',\r
       'caption', \r
       'url', \r
     ],\r
+    extend_settings: {\r
+      pettanr_pettan_commons_v01_licenses: {\r
+        columns: {\r
+          open: {\r
+          },\r
+          commercial: {\r
+          },\r
+          official: {\r
+          },\r
+          attribution: {\r
+          },\r
+          derive: {\r
+          }, \r
+          thumbnail: {\r
+          }, \r
+          gif_convert: {\r
+          }, \r
+          reverse: {\r
+          }, \r
+          sync_vh: {\r
+          }, \r
+          overlap: {\r
+          }, \r
+        },\r
+        column_names: [\r
+          'open', \r
+          'commercial', \r
+          'official', \r
+          'attribution:', \r
+          'derive', \r
+          'thumbnail', \r
+          'gif_convert', \r
+          'reverse', \r
+          'sync_vh', \r
+          'overlap', \r
+        ],\r
+      },\r
+    },\r
     associations: {\r
       has_many: [\r
         'licenses.by_license_group', \r
     }, \r
   },\r
   license: {\r
+    columns: {\r
+      license_group_id: {\r
+      },\r
+      license_group_classname: {\r
+      },\r
+      name: {\r
+      },\r
+      caption: {\r
+      },\r
+      system_picture_id: {\r
+      },\r
+      url: {\r
+      },\r
+      license_group_settings: {\r
+        type: 'extend',\r
+      }, \r
+    },\r
     column_names: [\r
       'license_group_id', \r
+      'license_group_classname', \r
       'name', \r
       'caption', \r
       'system_picture_id', \r
       'url', \r
-      'settings', \r
+      'license_group_settings', \r
       'credit_pictures', \r
     ],\r
     associations: {\r
index ebca4ef..74c4122 100644 (file)
@@ -1,9 +1,12 @@
 class Balloon < Peta::Element
   load_manifest
   belongs_to :speech_balloon
+  belongs_to :speech_balloon_template
   belongs_to :system_picture
   
   validates :speech_balloon_id, :numericality => {:allow_blank => true}
+  validates :speech_balloon_template_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :speech_balloon_template_classname, :presence => true, :length => {:maximum => 50}
   validates :system_picture_id, :presence => true, :numericality => true, :existence => {:both => false}
   validates :x, :presence => true, :numericality => true
   validates :y, :presence => true, :numericality => true
@@ -11,17 +14,12 @@ class Balloon < Peta::Element
   validates :height, :presence => true, :numericality => true, :natural_number => true
   validates :r, :presence => true, :numericality => true
 #  validates :caption, :presence => true
-  validates :settings, :extend_balloon => true
+  validates :speech_balloon_template_settings, :extend_balloon => true
 
   def url
     '/system_pictures/' + self.system_picture.filename
   end
   
-  def visible? operators
-    return false unless super
-    self.owner_model.visible? operators
-  end
-  
   def supply_default
     self.x = 0
     self.y = 0
index e06e621..70e8001 100644 (file)
@@ -6,6 +6,7 @@ class License < Peta::Item
   has_many :resource_pictures
   
   validates :license_group_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :license_group_classname, :presence => true, :length => {:maximum => 50}
   validates :name, :presence => true, :length => {:maximum => 50}
   validates :caption, :presence => true, :length => {:maximum => 30}
   validates :url, :presence => true, :length => {:maximum => 200}, :uniqueness => true, :url => {:message => I18n.t('errors.messages.url')} #{:allow_blank => true}
index cf81249..acd0a83 100644 (file)
@@ -1,10 +1,14 @@
 class Speech < Peta::Element
   load_manifest
   belongs_to :speech_balloon
+  belongs_to :speech_balloon_template
   belongs_to :writing_format
   
   validates :speech_balloon_id, :numericality => {:allow_blank => true}
+  validates :speech_balloon_template_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :speech_balloon_template_classname, :presence => true, :length => {:maximum => 50}
   validates :writing_format_id, :presence => true, :numericality => true, :existence => {:both => false}
+  validates :writing_format_classname, :presence => true, :length => {:maximum => 50}
   validates :font_size, :presence => true, :numericality => {:only_integer => false}
   validates :text_align, :presence => true, :numericality => true, :inclusion => { :in => 0..3 }
   validates :fore_color, :presence => true, :numericality => {:greater_than_or_equal_to => 0, :less_than => 0x1000000}
@@ -13,7 +17,8 @@ class Speech < Peta::Element
   validates :width, :presence => true, :numericality => true, :natural_number => true
   validates :height, :presence => true, :numericality => true, :natural_number => true
   validates :quotes, :length => {:maximum => 15}, :quotes_even => true
-  validates :settings, :extend_speech => true
+  validates :speech_balloon_template_settings, :extend_speech => true
+  #validates :writing_format_settings
   
   @@text_align_texts = ['left', 'left', 'right', 'center']
   
@@ -24,11 +29,6 @@ class Speech < Peta::Element
     self.height = 100
   end
   
-  def visible? operators
-    return false unless super
-    self.owner_model.visible? operators
-  end
-  
   def symbol_option
     self.speech_balloon.speech_balloon_template.symbol_option
   end
index 875041a..58c5654 100644 (file)
@@ -10,10 +10,10 @@ class SpeechBalloon < Peta::Element
   
   validates :panel_id, :numericality => {:allow_blank => true}
   validates :speech_balloon_template_id, :presence => true, :numericality => true, :existence => {:both => false}
-  validates :classname, :presence => true, :length => {:maximum => 50}
+  validates :speech_balloon_template_classname, :presence => true, :length => {:maximum => 50}
   validates :z, :presence => true, :numericality => {:greater_than => 0}
   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
-  validates :settings, :extend_speech_balloon => true
+  validates :speech_balloon_template_settings, :extend_speech_balloon => true
   
   def self.by_author_list_includes
     {
@@ -56,11 +56,6 @@ class SpeechBalloon < Peta::Element
     self.panel_id = pid
   end
   
-  def visible? operators
-    return false unless super
-    self.owner_model.visible? operators
-  end
-  
   def symbol_option
     self.speech_balloon_template.symbol_option
   end
index 461bca1..8edac06 100644 (file)
@@ -9,7 +9,7 @@ require 'ar_helper'
 require 'operator'
 require 'import_result'
 require 'common'
-require 'peta'
+require_dependency 'peta'
 # Initialize the rails application
 Pettanr::Application.initialize!
 require_dependency 'manifest'
@@ -18,5 +18,5 @@ require_dependency 'locmare'
 require_dependency 'editor'
 Manifest.manifest.init
 LocalManifest.manifest.init
-Manifest.manifest.system_resources_init
+Manifest.manifest.init_after_load_manifest
 Manifest.manifest.load_models_manifest
index fb90139..9da1165 100644 (file)
@@ -155,16 +155,19 @@ ja:
       speech_balloon:
         panel_id: コマ
         speech_balloon_template_id: フキダシテンプレート
-        classname: クラス名
+        speech_balloon_template_classname: フキダシクラス名
         z: 重なり
         t: 話順
         caption: 様子
-        settings: 拡張データ
+        speech_balloon_template_settings: フキダシ拡張データ
         created_at: 作成
         updated_at: 更新
       speech:
         speech_balloon_id: フキダシ
+        speech_balloon_template_id: フキダシテンプレート
+        speech_balloon_template_classname: フキダシクラス名
         writing_format_id: 記法
+        writing_format_classname: 記法クラス名
         content: セリフ
         font_size: 基本フォントサイズ
         text_align: テキスト揃え
@@ -174,18 +177,21 @@ ja:
         width: 幅
         height: 高さ
         quotes: カギカッコ
-        settings: 拡張データ
+        speech_balloon_template_settings: フキダシ拡張データ
+        writing_format_settings: 記法拡張データ
         created_at: 作成
         updated_at: 更新
       balloon:
         speech_balloon_id: フキダシ
+        speech_balloon_template_id: フキダシテンプレート
+        speech_balloon_template_classname: フキダシクラス名
         system_picture_id: 画像
         x: X
         y: Y
         width: 幅
         height: 高さ
         r: 角度
-        settings: 拡張データ
+        speech_balloon_template_settings: フキダシ拡張データ
         created_at: 作成
         updated_at: 更新
       ground_picture:
@@ -285,11 +291,12 @@ ja:
         updated_at: 更新
       license:
         license_group_id: ライセンスグループ
+        license_group_classname: ライセンスクラス名
         name: 管理名
         caption: 名前
         url: URL
         system_picture_id: マーク
-        settings: 拡張データ
+        license_group_settings: ライセンス拡張データ
         credit_pictures: クレジット内画像
         created_at: 作成
         updated_at: 更新
index 25fa4c9..e322a56 100644 (file)
@@ -2,13 +2,15 @@ class FixExtendSystem < ActiveRecord::Migration
   def up
     rename_column :speech_balloons, :classname, :speech_balloon_template_classname
     rename_column :speech_balloons, :settings, :speech_balloon_template_settings
-    add_column :balloons, :speech_balloon_template_classname, :string, :null => false, :limit => 50
+    add_column :balloons, :speech_balloon_template_id, :integer, :null => false, :default => 0
+    add_column :balloons, :speech_balloon_template_classname, :string, :null => false, :limit => 50, :default => 'noname'
     rename_column :balloons, :settings, :speech_balloon_template_settings
-    add_column :speeches, :speech_balloon_template_classname, :string, :null => false, :limit => 50
+    add_column :speeches, :speech_balloon_template_id, :integer, :null => false, :default => 0
+    add_column :speeches, :speech_balloon_template_classname, :string, :null => false, :limit => 50, :default => 'noname'
     rename_column :speeches, :settings, :speech_balloon_template_settings
-    add_column :speeches, :writing_format_classname, :string, :null => false, :limit => 50
-    rename_column :speeches, :settings, :writing_format_settings
-    add_column :licenses, :license_group_classname, :string, :null => false, :limit => 50
+    add_column :speeches, :writing_format_classname, :string, :null => false, :limit => 50, :default => 'noname'
+    add_column :speeches, :writing_format_settings, :text
+    add_column :licenses, :license_group_classname, :string, :null => false, :limit => 50, :default => 'noname'
     rename_column :licenses, :settings, :license_group_settings
   end
 
index 110a830..4812aa9 100644 (file)
@@ -2,26 +2,28 @@ class FixExtendSystemData < ActiveRecord::Migration
   def up
     Balloon.find(:all).each do |balloon|
       sbt = balloon.speech_balloon.speech_balloon_template
-      if balloon.speech_balloon_template_classname.blank?
+      if balloon.speech_balloon_template_classname == 'noname'
+        balloon.speech_balloon_template_id = sbt.id
         balloon.speech_balloon_template_classname = sbt.classname
         balloon.save!
       end
     end
     Speech.find(:all).each do |speech|
       sbt = speech.speech_balloon.speech_balloon_template
-      if speech.speech_balloon_template_classname.blank?
+      if speech.speech_balloon_template_classname == 'noname'
+        speech.speech_balloon_template_id = sbt.id
         speech.speech_balloon_template_classname = sbt.classname
         speech.save!
       end
       wf =  speech.writing_format
-      if speech.writing_format_classname.blank?
+      if speech.writing_format_classname == 'noname'
         speech.writing_format_classname = wf.classname
         speech.save!
       end
     end
     License.find(:all).each do |license|
       lg = license.license_group
-      if license.license_group_classname.blank?
+      if license.license_group_classname == 'noname'
         license.license_group_classname = lg.classname
         license.save!
       end
diff --git a/lib/locmare/booster.rb b/lib/locmare/booster.rb
new file mode 100644 (file)
index 0000000..c4bf673
--- /dev/null
@@ -0,0 +1,82 @@
+module Locmare
+  class Booster
+    attr :boost
+    
+    def initialize manifest, item
+      @manifest = manifest
+      @item = item
+      # no check
+      # return false unless self.resource.enable?
+      @item.extend self.engine_extend_module
+      @item.__send__ @manifest.setter_method_name, self.parsed_settings
+      @boosted = true
+    end
+    
+    def boosted?
+      @boosted
+    end
+    
+    # get engine resource from system resource manifest
+    def my_engine_resource
+      Manifest.manifest.system_resources.engine_resources[@item.table_name]
+    end
+    
+    # get snake_case engine name
+    # ex) circle_speech_balloon
+    # use to url, model_name generating
+    def engine_name
+      self.my_engine_resource.resource_items[@item.classname]
+    end
+    
+    def model_name
+      self.engine_name + '_' + @manifest.extend_item_name
+    end
+    
+    def enable?
+      self.my_engine_resource.resource_items.include? @item.classname
+    end
+    
+    # get engine's module name
+    def class_name
+      @item.attributes[@manifest.extend_column_name]
+    end
+    
+    def settings
+      @item.attributes[@manifest.settings_column_name]
+    end
+    
+    # name space for engine
+    def engine_module
+      Object.const_get self.class_name
+    end
+    
+    # extend module in engine
+    # ex) CircleSpeechBalloon::SpeechBalloonModule
+    def engine_extend_module
+      self.engine_module.const_get @manifest.extend_module_name
+    end
+    
+    # extend settings data model in engine
+    # ex) CircleSpeechBalloon::SpeechBalloon
+    def engine_extend_model
+      self.engine_module.const_get @manifest.extend_model_name
+    end
+    
+    # get system resource instance
+    def resource
+      r = @item.__send__ @manifest.name
+      raise 'resource not found' unless r
+      r
+    end
+    
+    def parsed_settings
+      if self.settings.blank?
+        {}
+      else
+        JSON.parse(self.settings)
+      end
+    end
+    
+  end
+end
+
index e1672c4..1542627 100644 (file)
@@ -10,6 +10,9 @@ module Locmare
       @item_name = item_name
       @item = item
       @operators = operators
+      # feasible show parsed extend data
+      @item.boost 'post'
+      
       @profiler_manifest = LocalManifest.manifest.profilers[@item_name]
       @template_dir = 'templates/r/profiler/'
       @header = Header.new self
index 8e33c12..f56e8ce 100644 (file)
@@ -12,7 +12,11 @@ module Locmare
       end
       
       def value
-        self.item.attributes[@column_name]
+        if self.item.extend_column?(@column_name)
+          
+        else
+          self.item.attributes[@column_name]
+        end
       end
       
       def note
index c48cf98..88c634c 100644 (file)
@@ -5,7 +5,7 @@ module Manifest
   module ItemModule
     class BasePeta < ManifestBase::TypeNameArgs
       
-      attr :boost
+      attr :boost ,:parent_model_name
       
       def set_default
         super
@@ -14,18 +14,25 @@ module Manifest
       
       def init
         super
+        @parent_model_name = nil  # init at leaf, element
         @boost = ManifestBase.load_name_values self, @args, 'boost', Boost
       end
       
+      def init_after_load_manifest
+        @boost.each do |boost_name, boost_manifest|
+          boost_manifest.init_after_load_manifest
+        end
+      end
+      
       def element?
         @parent_model_name != nil
       end
       
-      def boosts item, level
-        @boost.each do |name, manifest|
-          next unless manifest.level == level
-          Boost::ItemBooster.new(manifest, item).boost
+      def extend_column? column_name
+        @boost.each do |boost_name, boost_manifest|
+          return true if boost_manifest.extend_column_name == column_name
         end
+        false
       end
       
       def supply_defaults item
@@ -35,7 +42,7 @@ module Manifest
       end
       
       def model
-        ::Manifest.manifest.models[@name]
+        ::Manifest.item_name_to_model @name
       end
       
     end
index 1c3e7fa..782d787 100644 (file)
@@ -2,7 +2,9 @@ module Manifest
   module ItemModule
     class Boost < ManifestBase::NameValues
       attr :level, :extend_column_name, :settings_column_name, 
-        :foreign_key, :setter_method_name, :getter_method_name
+        :foreign_key, :extend_model_class_name, :extend_item_name, 
+        :setter_method_name, :getter_method_name, 
+        :extend_module_name
       
       def set_default
         super
@@ -10,8 +12,6 @@ module Manifest
         @values['extend_column_name'] ||= @name + '_classname'
         @values['settings_column_name'] ||= @name + '_settings'
         @values['foreign_key'] ||= @name + '_id'
-        @values['setter_method_name'] ||= @name + '_extend='
-        @values['getter_method_name'] ||= @name + '_extend'
       end
       
       def init
@@ -20,72 +20,22 @@ module Manifest
         @extend_column_name = @values['extend_column_name']
         @settings_column_name = @values['settings_column_name']
         @foreign_key = @values['foreign_key']
-        @setter_method_name = @values['setter_method_name']
-        @getter_method_name = @values['getter_method_name']
-      end
-      
-      def extend_model_name
-        @parent.model.singular
       end
       
-      def extend_module_name
-        @parent.model.singular + 'Module'
+      def init_after_load_manifest
+        # string name can't change before load manifest
+        @values['extend_model_class_name'] ||= @parent.model.singular
+        @values['extend_item_name'] ||= @parent.model.item_name
+        @values['setter_method_name'] ||= @parent.model.item_name + '_extend='
+        @values['getter_method_name'] ||= @parent.model.item_name + '_extend'
+        
+        @extend_model_class_name = @values['extend_model_class_name']
+        @extend_item_name = @values['extend_item_name']
+        @setter_method_name = @values['setter_method_name']
+        @getter_method_name = @values['getter_method_name']
+        @extend_module_name = @extend_model_class_name + 'Module'
       end
       
-      class ItemBooster
-        def initialize manifest, item
-          @manifest = manifest
-          @item = item
-        end
-        
-        # get engine's name
-        def class_name
-          @item.attributes[@manifest.extend_column_name]
-        end
-        
-        def settings
-          @item.attributes[@manifest.settings_column_name]
-        end
-        
-        # name space for engine
-        def engine_module
-          Object.const_get self.class_name(@item)
-        end
-        
-        # extend module in engine
-        # ex) CircleSpeechBalloon::SpeechBalloonModule
-        def engine_extend_module
-          self.engine_module.const_get @manifest.extend_module_name
-        end
-        
-        # extend settings data model in engine
-        def engine_extend_model
-          self.engine_module.const_get @manifest.extend_module_name
-        end
-        
-        # get system resource instance
-        def resource
-          r = @item.__send__ @manifest.name
-          raise 'resource not found' unless r
-          r
-        end
-        
-        def parsed_settings
-          if self.settings.blank?
-            {}
-          else
-            JSON.parse(self.settings)
-          end
-        end
-        
-        def boost
-          # no check
-          # return false unless self.resource.enable?
-          @item.extend self.engine_extend_module
-          @item.__send__ @manifest.setter_method_name, self.parsed_settings
-        end
-        
-      end
       
       def supply_default item
         self.engine_model(item).engine_extend_module.supply_default item, self
index 070d712..ba0bd1b 100644 (file)
@@ -19,9 +19,13 @@ module Manifest
       @items = ManifestBase.load_type_name_args(self, @global_json, 'items', ItemFactory)
       @controllers = Controller.load(self, @global_json, 'controllers')
       @models = Model.load(self, @global_json, 'models')
+      # 
+      @items.each do |name, peta_manifest|
+        peta_manifest.init_after_load_manifest
+      end
     end
     
-    def system_resources_init
+    def init_after_load_manifest
       @system_resources.init
     end
     
index fac8e11..5f9f9e5 100644 (file)
@@ -26,6 +26,13 @@ module Peta
       end
     end
     
+    # Instance Methods
+    
+    def visible? operators
+      return false unless super
+      true
+    end
+    
     def self.list_opt_for_panel
       {}
     end
index c738aaa..7cdead1 100644 (file)
@@ -99,7 +99,7 @@ module Peta
       opt = {}
       opt.merge!(self.show_opt)
       item = self.find(item_id, opt)
-      item.boosts 'show'
+      item.boost 'show'
       raise ActiveRecord::Forbidden unless item.visible?(operators)
       item
     end
@@ -157,8 +157,15 @@ module Peta
       end
     end
     
-    def boosts level
-      self.class.my_peta.boosts self, level
+    def boost level
+      self.class.my_peta.boost.each do |boost_name, boost_manifest|
+        next unless boost_manifest.level == level
+        Locmare::Booster.new(boost_manifest, self)
+      end
+    end
+    
+    def extend_column? column_name
+      self.class.my_peta.extend_column? column_name
     end
     
     def supply_default
index 243c60d..a877c5a 100644 (file)
@@ -22,6 +22,11 @@ module Peta
       self.parent_model
     end
     
+    def visible? operators
+      return false unless super
+      self.class.root_model.visible? operators
+    end
+    
     def self.play_list_where cid
       ['scroll_panels.scroll_id = ?', cid]
     end
index 1e340a9..7b9574b 100644 (file)
@@ -1,6 +1,6 @@
 class ExtendBalloonValidator < ActiveModel::EachValidator\r
   def validate_each(record, attribute, value)\r
-    record.errors[attribute] << (options[:message] || I18n.t('activerecord.errors.messages.balloon_extend')) unless record.extend_balloon.valid?\r
+    record.errors[attribute] << (options[:message] || I18n.t('activerecord.errors.messages.balloon_extend')) unless true #record.extend_balloon.valid?\r
   end\r
 end\r
 \r
index 598bd41..755c0e0 100644 (file)
@@ -1,6 +1,6 @@
 class ExtendSpeechValidator < ActiveModel::EachValidator\r
   def validate_each(record, attribute, value)\r
-    record.errors[attribute] << (options[:message] || I18n.t('activerecord.errors.messages.speech_extend')) unless record.extend_speech.valid?\r
+    record.errors[attribute] << (options[:message] || I18n.t('activerecord.errors.messages.speech_extend')) unless true # record.extend_speech.valid?\r
   end\r
 end\r
 \r
index e7a991f..5f5e6e8 100644 (file)
@@ -28,7 +28,6 @@
       }\r
     },\r
     "scroll_panel": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
@@ -66,7 +65,6 @@
       }\r
     },\r
     "story": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
@@ -97,7 +95,6 @@
       }\r
     },\r
     "story_sheet": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "sheet_panel": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "panel_picture": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "speech_balloon": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "speech": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "balloon": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "ground_picture": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       }\r
     },\r
     "ground_color": {\r
-      "tree_name": "owner",\r
       "lists": {\r
         "public": {\r
           "type": "public"\r
       "column_names": [\r
         "panel_id",\r
         "speech_balloon_template_id",\r
-        "classname",\r
+        "speech_balloon_template_classname",\r
         "z",\r
         "t",\r
-        "settings",\r
+        "speech_balloon_template_settings",\r
         "caption"\r
       ],\r
       "associations": {\r
     "speech": {\r
       "column_names": [\r
         "speech_balloon_id",\r
+        "speech_balloon_template_id",\r
+        "speech_balloon_template_classname",\r
         "writing_format_id",\r
+        "writing_format_classname",\r
         "content",\r
         "font_size",\r
         "text_align",\r
         "width",\r
         "height",\r
         "quotes",\r
-        "settings"\r
+        "speech_balloon_template_settings",\r
+        "writing_format_settings"\r
       ],\r
       "associations": {\r
         "belongs_to": [\r
     "balloon": {\r
       "column_names": [\r
         "speech_balloon_id",\r
+        "speech_balloon_template_id",\r
+        "speech_balloon_template_classname",\r
         "system_picture_id",\r
         "x",\r
         "y",\r
         "width",\r
         "height",\r
         "r",\r
-        "settings"\r
+        "speech_balloon_template_settings"\r
       ],\r
       "associations": {\r
         "belongs_to": [\r
     "license": {\r
       "column_names": [\r
         "license_group_id",\r
+        "license_group_classname",\r
         "name",\r
         "caption",\r
         "system_picture_id",\r
         "url",\r
-        "settings",\r
+        "license_group_settings",\r
         "credit_pictures"\r
       ],\r
       "associations": {\r
               }\r
             }\r
           },\r
-          "speech_balloon.classname": {\r
+          "speech_balloon.speech_balloon_template_classname": {\r
             "args": {\r
               "label": {\r
                 "type": "none"\r
               }\r
             }\r
           },\r
-          "speech_balloon.settings": {\r
+          "speech_balloon.speech_balloon_template_settings": {\r
             "args": {\r
               "label": {\r
                 "type": "none"\r
               }\r
             }\r
           },\r
+          "balloon.speech_balloon_template_id": {\r
+            "type": "part",\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
           "balloon.system_picture_id": {\r
             "type": "part",\r
             "args": {\r
               "row_break": true\r
             }\r
           },\r
-          "balloon.settings": {\r
+          "balloon.speech_balloon_template_classname": {\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
+          "balloon.speech_balloon_template_settings": {\r
             "type": "part",\r
             "args": {\r
               "label": {\r
               }\r
             }\r
           },\r
+          "speech.speech_balloon_template_id": {\r
+            "type": "part",\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
           "speech.x": {\r
             "type": "part",\r
             "args": {\r
               }\r
             }\r
           },\r
-          "speech.settings": {\r
+          "speech.speech_balloon_template_classname": {\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
+          "speech.writing_format_classname": {\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
+          "speech.speech_balloon_template_settings": {\r
+            "type": "part",\r
+            "args": {\r
+              "label": {\r
+                "type": "none"\r
+              },\r
+              "tag": {\r
+                "type": "hidden"\r
+              }\r
+            }\r
+          },\r
+          "speech.writing_format_settings": {\r
             "type": "part",\r
             "args": {\r
               "label": {\r
           "balloon.id",\r
           "balloon.speech_balloon_id",\r
           "balloon.system_picture_id",\r
-          "balloon.settings",\r
+          "balloon.speech_balloon_template_id",\r
+          "balloon.speech_balloon_template_classname",\r
+          "balloon.speech_balloon_template_settings",\r
           "speech.writing_format_id",\r
           "speech.font_size",\r
           "speech.text_align",\r
           "speech.y",\r
           "speech.width",\r
           "speech.height",\r
-          "speech.settings",\r
+          "speech.speech_balloon_template_id",\r
+          "speech.speech_balloon_template_classname",\r
+          "speech.speech_balloon_template_settings",\r
+          "speech.writing_format_classname",\r
+          "speech.writing_format_settings",\r
           "speech_balloon.id",\r
           "speech_balloon.panel_id",\r
           "speech_balloon.speech_balloon_template_id",\r
-          "speech_balloon.classname",\r
+          "speech_balloon.speech_balloon_template_classname",\r
           "speech_balloon.z",\r
           "speech_balloon.t",\r
-          "speech_balloon.settings"\r
+          "speech_balloon.speech_balloon_template_settings"\r
         ]\r
       },\r
       "PlainSpeechBalloon": {\r
           "balloon.id",\r
           "balloon.speech_balloon_id",\r
           "balloon.system_picture_id",\r
-          "balloon.settings",\r
+          "balloon.speech_balloon_template_id",\r
+          "balloon.speech_balloon_template_classname",\r
+          "balloon.speech_balloon_template_settings",\r
           "speech.writing_format_id",\r
           "speech.font_size",\r
           "speech.text_align",\r
           "speech.y",\r
           "speech.width",\r
           "speech.height",\r
-          "speech.settings",\r
+          "speech.speech_balloon_template_id",\r
+          "speech.speech_balloon_template_classname",\r
+          "speech.speech_balloon_template_settings",\r
+          "speech.writing_format_classname",\r
+          "speech.writing_format_settings",\r
           "speech_balloon.id",\r
           "speech_balloon.panel_id",\r
           "speech_balloon.speech_balloon_template_id",\r
-          "speech_balloon.classname",\r
+          "speech_balloon.speech_balloon_template_classname",\r
           "speech_balloon.z",\r
           "speech_balloon.t",\r
-          "speech_balloon.settings"\r
+          "speech_balloon.speech_balloon_template_settings"\r
         ]\r
       },\r
       "SquareSpeechBalloon": {\r
           "balloon.id",\r
           "balloon.speech_balloon_id",\r
           "balloon.system_picture_id",\r
-          "balloon.settings",\r
+          "balloon.speech_balloon_template_id",\r
+          "balloon.speech_balloon_template_classname",\r
+          "balloon.speech_balloon_template_settings",\r
           "speech.writing_format_id",\r
           "speech.font_size",\r
           "speech.text_align",\r
           "speech.y",\r
           "speech.width",\r
           "speech.height",\r
-          "speech.settings",\r
+          "speech.speech_balloon_template_id",\r
+          "speech.speech_balloon_template_classname",\r
+          "speech.speech_balloon_template_settings",\r
+          "speech.writing_format_classname",\r
+          "speech.writing_format_settings",\r
           "speech_balloon.id",\r
           "speech_balloon.panel_id",\r
           "speech_balloon.speech_balloon_template_id",\r
-          "speech_balloon.classname",\r
+          "speech_balloon.speech_balloon_template_classname",\r
           "speech_balloon.z",\r
           "speech_balloon.t",\r
-          "speech_balloon.settings"\r
+          "speech_balloon.speech_balloon_template_settings"\r
         ]\r
       }\r
     }\r
index fbf9b36..6875b99 100644 (file)
       "args": {\r
         "parent_model_name": "panel",\r
         "boost": {\r
-          "speech_balloon_template": {}\r
+          "speech_balloon_template": {\r
+            "setter_method_name": "extend_speech_balloon=",\r
+            "getter_method_name": "extend_speech_balloon"\r
+          }\r
         }\r
       }\r
     },\r
       "args": {\r
         "parent_model_name": "speech_balloon",\r
         "boost": {\r
-          "speech_balloon_template": {}\r
+          "speech_balloon_template": {\r
+            "setter_method_name": "extend_speech_balloon=",\r
+            "getter_method_name": "extend_speech_balloon"\r
+          }\r
         }\r
       }\r
     },\r
         "parent_model_name": "speech_balloon",\r
         "boost": {\r
           "writing_format": {},\r
-          "speech_balloon_template": {}\r
+          "speech_balloon_template": {\r
+            "setter_method_name": "extend_speech_balloon=",\r
+            "getter_method_name": "extend_speech_balloon"\r
+          }\r
         }\r
       }\r
     },\r
       "args": {\r
         "parent_model_name": "license_group",\r
         "boost": {\r
-          "license_group": {}\r
+          "license_group": {\r
+            "extend_item_name": "attribute"\r
+          }\r
         }\r
       }\r
     },\r
       }\r
     },\r
     "speech_balloon": {\r
-      "extend_column_name": "classname",\r
       "associations": {\r
         "belongs_to": {\r
           "panel": {}\r
             "number": true\r
           }\r
         },\r
-        "classname": {\r
+        "speech_balloon_template_classname": {\r
           "type": "text",\r
           "rules": {\r
             "required": true\r
             "min": 0\r
           }\r
         },\r
-        "settings": {\r
+        "speech_balloon_template_settings": {\r
           "type": "text",\r
           "rules": {}\r
         },\r
             "number": true\r
           }\r
         },\r
+        "speech_balloon_template_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        },\r
+        "speech_balloon_template_classname": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
         "system_picture_id": {\r
           "type": "number",\r
           "rules": {\r
             "number": true\r
           }\r
         },\r
-        "settings": {\r
+        "speech_balloon_template_settings": {\r
           "type": "text",\r
           "rules": {}\r
         }\r
             "number": true\r
           }\r
         },\r
+        "speech_balloon_template_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        },\r
+        "speech_balloon_template_classname": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
         "writing_format_id": {\r
           "type": "number",\r
           "source": {\r
             "number": true\r
           }\r
         },\r
+        "writing_format_classname": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
         "content": {\r
           "type": "text",\r
           "rules": {}\r
           "type": "text",\r
           "rules": {}\r
         },\r
-        "settings": {\r
+        "speech_balloon_template_settings": {\r
+          "type": "text",\r
+          "rules": {}\r
+        },\r
+        "writing_format_settings": {\r
           "type": "text",\r
           "rules": {}\r
         }\r
       }\r
     },\r
     "speech_balloon_template": {\r
-      "extend_column_name": "classname",\r
       "associations": {\r
         "belongs_to": {\r
           "system_picture": {}\r
       }\r
     },\r
     "writing_format": {\r
-      "extend_column_name": "classname",\r
       "associations": {\r
         "belongs_to": {\r
           "system_picture": {}\r
       }\r
     },\r
     "license_group": {\r
-      "extend_column_name": "classname",\r
       "associations": {\r
         "belongs_to": {},\r
         "has_many": {\r
             "number": true\r
           }\r
         },\r
+        "license_group_classname": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
         "name": {\r
           "type": "text",\r
           "rules": {\r
             "required": true\r
           }\r
         },\r
-        "settings": {\r
+        "license_group_settings": {\r
           "type": "text",\r
           "rules": {}\r
         },\r
           }\r
         }\r
       }\r
+    },\r
+    "circle_speech_balloon_speech_balloon": {\r
+      "attributes": {\r
+        "width": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "pettanr_pettan_commons_v01_licenses_attribute": {\r
+      "attributes": {\r
+        "license_id": {\r
+          "type": "number",\r
+          "rules": {\r
+            "required": true,\r
+            "number": true\r
+          }\r
+        },\r
+        "artist_name": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
+        "caption": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        },\r
+        "sources": {\r
+          "type": "text",\r
+          "rules": {\r
+            "required": true\r
+          }\r
+        }\r
+      }\r
     }\r
   },\r
   "system_resources": {\r