Top > 開発ガイド > コンポーネント開発チュートリアル > 02 コンポーネントの初期化

02 コンポーネントの初期化

Newsコンポーネントの作成

ここからはニュースコンポーネントを題材として一歩踏み込んだ解説をしていきます。

雛型の作成

まずはコンポーネントの雛型を作成します。

 > ruby script/generate rubricks_component news post main
      create  components/news
      create  components/news/post
      create  components/news/languages
      create  components/news/preload
      create  components/news/_install
      create  components/news/_install/db
      create  components/news/_install/images
      create  components/news/_install/javascripts
      create  components/news/_install/stylesheets
      create  components/news/post_controller.rb
      create  components/news/post_helper.rb
      create  components/news/post/main.rhtml
      create  components/news/languages/japanese.rb
      create  components/news/languages/english.rb
      create  components/news/preload/_preload.rhtml
      create  components/news/_install/component_info.rb
      create  components/news/_install/db/001_news_schema_001.rb
      create  components/news/_install/images/news.gif
      create  components/news/_install/images/news_active.gif
      create  components/news/_install/javascripts/news.js
      create  components/news/_install/stylesheets/style.js
     created  install/news.rzip
   installed  news

DBの準備

投稿されたニュースを格納するテーブルを準備します。

DBスキーマファイルの編集

class NewsSchema001 < ActiveRecord::Migration
  def self.up
    create_table :news_items, :force => true do |t|
      t.column :rubricks_user_id,   :integer,                   :default => 0,      :null => false
      t.column :title,              :string,    :limit => 192,  :default => '',     :null => false
      t.column :article,            :text,                                          :null => false
      t.column :created_at,         :datetime
    end
  end

  def self.down
    drop_table :news_items
  end
end

▲ /_install/db/001_news_schema_001.rb

コンポーネントの初期化

Rubricksにはコンポーネントを初期化するためのスクリプトが付属しています。実行すると、擬似的にコンポーネントのアンインストール・インストールを行うことで初期化が行われます。

 > ruby script/component_init news
news installed.

コンポーネント初期化スクリプトは以下のような場面で使用できます。

  • DBスキーマを変更した時
  • コンポーネント情報定義ファイルを編集した時

基本機能の実装

モデルの作成

 > ruby script/generate rubricks_model news news_item
      exists  components/news
      create  components/news/news_item.rb

コントローラの追加作成

 > ruby script/generate rubricks_controller news index main show block
      exists  components/news
      create  components/news/index
      create  components/news/index/main.rhtml
      create  components/news/index/show.rhtml
      create  components/news/index/block.rhtml
      create  components/news/index_controller.rb
      create  components/news/index_helper.rb

ニュース投稿処理の実装

まずはニュース投稿処理を実装します。

  • ファイル内に日本語が記述されている場合はUTF-8で保存して下さい
  • ニュース投稿画面に「リストエリア」は不要なため「詳細エリア」のみの表示に変更しています (参照)
  • 「form_main_tag」というRubricks独自のヘルパを利用しています (参照)
  • 「rollover_swap」というRubricks独自のヘルパを利用しています (参照)
  • フィードバックメッセージ及びエラーメッセージウィンドウを利用しています。
class News::NewsItem < ActiveRecord::Base
  validates_length_of       :title, :in => 1..64
  validates_length_of       :title, :in => 1..10000
end

▲ /news_item.rb

class News::PostController < ApplicationController
  define_page
  uses_component_template_root

  def main
  end

  def create
    begin
      ActiveRecord::Base.transaction do
        ni = News::NewsItem.new(params[:news_item])
        ni.rubricks_user_id = current_user.id
        ni.save!
      end
    rescue Exception => ex
      logger.error(ex.message)
      logger.error(ex.backtrace.join("\n  "))
      flash[:news_error] = 'ニュースの投稿に失敗しました。'
    else
      flash[:news_message] = 'ニュースを投稿しました。'
    end
    render :action => 'main'
  end
end

▲ /post_controller.rb

<div class="rubricks_general_frame_borderless">
  <% render_operation_bar do %>
    Operation Bar
  <% end %>
  <% render_content_body do %>
    <% render_detail_frame('00') do %>
      <% render_detail('00', 'ニュース投稿') do %>
        <% form_main_tag(:url => {:controller => '/news/post', :action => 'create'}, :html => {:id => 'news_post_form'}) do %>
          <table class="rubricks_general_table">
            <tr class="rubricks_general_table_even">
              <td>タイトル</td>
              <td><%= text_field 'news_item', 'title', :size => 32 %></td>
            </tr>
            <tr class="rubricks_general_table_even">
              <td>記事</td>
              <td><%= text_area 'news_item', 'article', :cols => 70, :rows => 4 %></td>
            </tr>
            <tr class="rubricks_general_table_even">
              <td style="padding-right:20px; text-align:right;" colspan="2">
                <%= submit_tag '投稿', {:id => 'news_post_button', :class => 'submit_inactive swap'} %>
                <%= rollover_swap('news_post_button') %>
              </td>
            </tr>
          </table>
        <% end %>
      <% end %>
    <% end %>
  <% end %>
</div>
<%= flash_for_feedback_msg(:news_message) %>
<%= flash_for_error_msg(:news_error) %>

▲ /post/main.rhtml

ニュース閲覧処理の実装

続いてニュース閲覧処理を実装します。

class News::IndexController < ApplicationController
  define_page
  uses_component_template_root

  def main
    @ni_list = News::NewsItem.find(:all)
  end

  def show
    @ni = News::NewsItem.find(params[:id])
  end

  def block
  end
end

▲ /index_controller.rb

<div class="rubricks_general_frame_borderless">
  <% render_operation_bar do %>
    Operation Bar
  <% end %>
  <% render_content_body do %>
    <% render_list_frame('01') do %>
      <% render_list('01', '[_Common_List]') do %>
        <% @ni_list.each do |ni| %>
          <%= link_to_remote(hl(ni.title), {:url => {:controller => '/news/index', :action => 'show', :id => ni.id}, :update => 'news_detail_area'}) %>
        <% end %>
      <% end %>
    <% end %>
    <% render_detail_frame('01') do %>
      <% render_detail('01', '[_Common_Details]') do %>
        <div id="news_detail_area">
          ニュースを選択して下さい。
        </div>
      <% end %>
    <% end %>
  <% end %>
</div>

▲ /index/main.rhtml

<table id="news_item_detail" class="rubricks_general_table">
  <tr class="rubricks_general_table_even">
    <td style="width: 20%;"><%= hl('[_Common_Title]') %></td>
    <td style="width: 80%;"><%= hl(@ni.title) %></td>
  </tr>
  <tr class="rubricks_general_table_even">
    <td><%= hl('[_Common_Content]') %></td>
    <td><%= hl(@ni.article) %></td>
  </tr>
</table>

▲ /index/show.rhtml

動作確認

さて、これで基本機能の実装は完了しました。ブラウザで動作を確認してみましょう。

期待していた状態と異なりますね。ニュース投稿に関しては問題なくできていますが、ニュースの閲覧ができません。メニューが表示されていないためニュース閲覧画面が表示できないようです。

メニューの追加登録

コンポーネントに所属するメニューはコンポーネント情報定義ファイルに記述します。

class News::ComponentInfo < RubricksComponentInfo
  def initialize
    @display_name   = '[_News_Info_Title]'
    @version        = '-'
    @description    = '[_News_Info_Description]'
    @author         = '-'
    @license        = '-'
    @functions      = []
    @menus = [
      {
        :extend_page    => 'main',
        :title          => '[_News_Menu_TitleIndex]',
        :controller     => '/news/index',
        :action         => 'main',
        :function       => 'access',
        :description    => '[_News_Menu_DescIndex]',
      },
      {
        :extend_page    => 'main',
        :title          => '[_News_Menu_TitlePost]',
        :controller     => '/news/post',
        :action         => 'main',
        :function       => 'access',
        :description    => '[_News_Menu_DescPost]',
      }
    ]
  end
end

▲ /_install/component_info.rb

module RubricksLanguage
  def define_lang
    @lang.merge!({
      '_News_Info_Title'          => 'News',
      '_News_Info_Description'    => '',
      '_News_Menu_TitleIndex'     => 'ニュース閲覧',
      '_News_Menu_DescIndex'      => '',
      '_News_Menu_TitlePost'      => 'ニュース投稿',
      '_News_Menu_DescPost'       => '',
    })
  end
end

▲ /languages/japanese.rb

module RubricksLanguage
  def define_lang
    @lang.merge!({
      '_News_Info_Title'          => 'News',
      '_News_Info_Description'    => '',
      '_News_Menu_TitleIndex'     => 'News List',
      '_News_Menu_DescIndex'      => '',
      '_News_Menu_TitlePost'      => 'News Post',
      '_News_Menu_DescPost'       => '',
    })
  end
end

▲ /languages/english.rb

コンポーネント情報定義ファイルを編集したので、コンポーネントの初期化を行います。

 > ruby script/component_init news
news installed.

動作確認

改めてブラウザで動作を確認してみましょう。

Attachments