Categories

open all | close all

Tags


Search

Archive for October 2007

複合キーの使い方

複合キーのプラグインを使って,当面のモデル化は大体大丈夫そうです。作業メモとして手順と設定を書いておきます。

プラグインのインストールは
gem install composite_primary_keys

で行います。

environment.rbには
require 'rubygems'
require 'composite_primary_keys'

と書いておきます。

まず,Team回りの設定から。Teamクラスには下のように二つのbelongs_toを設定。
class Team < ActiveRecord::Base
  set_primary_keys :tmember, :tblog
  set_base_name :team
  belongs_to :blog, :foreign_key => 'tblog'
  belongs_to :member, :foreign_key => 'tmember'
end

Blogクラスには以下の2行を追加
  has_many :teams, :class_name=>'Team' ,:foreign_key => 'tblog'
  has_many :members, :class_name=>'Member' ,:through=>:teams

同様にMemberクラスにも
  has_many :teams, :class_name=>'Team' ,:foreign_key => 'tmember'
  has_many :blogs, :class_name=>'Blog' ,:through=>:teams
を追加しました。これでmember.blogsとか,blog.membersといった形で参照できるようになります。

次に,もうちょっと単純ですが,スキン関係とテンプレート関係を設定。nucleus_skin_descテーブルにはスキンのIDと名前,説明が,nucleus_skinテーブルには各パートがスキンのIDとパート名をキーとして入っています。

skin_descの方をSkinモデルにします。
class Skin < ActiveRecord::Base
  set_base_name :skin_desc
  set_primary_key :sdnumber
  has_many :parts, :class_name=>'SkinPart' ,:foreign_key => 'sdesc'
end

skinテーブルをSkinPartモデルにします。
class SkinPart < ActiveRecord::Base
  set_base_name :skin
  set_primary_keys :sdesc, :stype
  belongs_to :skin, :foreign_key => :sdesc
end

使い方はこんな感じ。
「default」スキンを獲得
>> skin = Skin.find_by_sdname('default')
skin = Skin.find_by_sdname('default')
=> #"text/html", "sdnumber"=>"5", "sdincmode"=>"skindir", "sddesc"=>"Nucleus CMS default skin", "sdincpref"=>"default/", "sdname"=>"default"}>

このスキンの「index」パートを獲得
>> indexpart = skin.parts.find_by_stype('index')
indexpart = skin.skin_parts.find_by_stype('index')
=> #
以下略

SkinのIDが分かっているならば直接パートの内容を得ることもできます。
>> indexpart = SkinPart.find([5, 'index'])
indexpart = SkinPart.find([5, 'index'])
=> #
以下略

実際のパートの内容にはindexpart.scontentでアクセスできます。テンプレートも同様です。

追記:
  def part(type)
    SkinPart.find([self.id, type]).scontent
  end

とSkinクラスに追加するとskin.part('index')とかで簡単にパートの内容にアクセスできます。多分この方が楽だし速い。

31 Oct, 2007 | General | | Andy | Leave comment - 0 -

リレーション追加

カテゴリーや,コメント,メンバーといったテーブルについてもモデル化を進めています。
一つ引っかかっているのが「チーム」のテーブル。このテーブルはブログIDとメンバーのID,それとAdminのフィールドという三つのフィールドしかなく,主キーがありません。

Railsではこういったときのブログとメンバーの関係をhas_and_belongs_to_many(HABTM)と言っていますが,このときの中間テーブルに相当するのがチームです。ほかにフィールドがなければ問題ないのですが,Adminのフィールドがあるので,そのままではこのモデルにうまくはまりません。「push_with_attributes」という形でフィールドを追加できるという機能もあるのですが,近い将来廃止されるようなので使えません。主キーがあればhas_many; throughといった機能が使えるようですが,テーブル構造を変えるのは今の段階ではちょっと避けたいところ。

Composite Primary Keysというプラグインを使ってみることにしましたが,これがどこまでうまく働いてくれるかは微妙です。

31 Oct, 2007 | General | | Andy | Leave comment - 0 -

ブログとアイテムのリレーション

テストはまだなんだかうまくいかないところもありますが,RadRailsからのコンソールの使い方がやっと分かったので,そちらでテスト。一応リレーションの設定は動いているようです。アイテムとブログの場合はアイテムがブログにbelongs_to,ブログから見るとアイテムをhas_manyするという関係なので,以下のようにしました。

class Item < ActiveRecord::Base
  set_primary_key :inumber
  set_base_name :item
  belongs_to :blog, :foreign_key => 'iblog'
end

class Blog < ActiveRecord::Base
  set_primary_key :bnumber
  set_base_name :blog
  has_many :items, :class_name=>'Item' ,:foreign_key => 'iblog'
end

両方にiblogを書くのがなんだか解せない感じもしますが,一応動いているのでいいことにしておきます。これで例えばブログからだったら
blog = Blog.find(1)
とか
blog = Blog.find(:first, :conditions=>"bshortname = 'test'")
でブログ・オブジェクトを獲得した後
blog.items
で,アイテムの配列が得られます。
逆にアイテムからだったら
item.blog
でブログ・オブジェクトにアクセスできます。
モデルに関してはこれで他のテーブルのモデル作成とリレーションを設定していけばいいはず。

追記
blog = Blog.find_by_bshortname("test")
でもブログ・オブジェクトが獲得できるはずです。

30 Oct, 2007 | General | | Andy | Leave comment - 0 -

作業メモ

まだリレーションのテストは確認していないけど一応テストは動くようになったので,ここまでの作業メモ。まずはプリフィクスを付けるプラグインは以下のようにして,environment.rbの中でset_prefixでプレフィクスを設定。

# Prefixed
module ActiveRecord
  class Base
    class <<Base
      alias :original_table_name :table_name

      def set_base_name(basename)
        @base_name = basename
      end
      
      def set_prefix(prefix)
        @@nucleus_prefix = prefix
      end
      
      def table_name
        if @base_name 
           @@nucleus_prefix + @base_name.to_s
        else
           original_table_name
        end
      end
     end 
  end
end

後は,各クラスではset_base_nameでベースネームを設定(これってアクセサにすべきだった? ちょっとかっこ悪いけどまあいいや)。
テストの方は モデルクラス_test.rb の中でfixtureとしてプリフィクス付きのテーブル名を指定。あわせてfixturesの中のYAMLのファイル名もテーブル名と同じものに変更。さらにYAMLの中でidとなっているところは,実際のID(inumberなど)に修正。

今日はここまで(受験の神様風,笑)


27 Oct, 2007 | General | | Andy | Leave comment - 0 -

これからの進め方

プレフィクスの問題に関連して,Tracを見るといくつかパッチなどが出ています。
一つを適用してみたところ,確かに生成するテーブル名については正しくなったのですが,
それでもやはりエラーが残ります(どこでかちょっと分からないのですが)。
この問題にいつまでもわずらわされるのはあまりにも非生産的なので,
プレフィクスについてはtable_name_prefixを使わずにアプリ内部で処理,
テストに関してはテーブル名を変えたときのfixtureの修正ということで
対処していきたいと思います。このとき,fixture用のYAMLファイルに
プリフィクスを付けないといけないので,かなり汚いのですが,あくまでテストなので
その汚さには目をつぶろうと思います。

26 Oct, 2007 | General | | Andy | Leave comment - 0 -

シンプルな状態で試してみた

自己流のコードが入っていると,何が問題になっているのか分からなくなってしまうので,
一回何もないアプリから始めて,ActiveRecord::Base.table_name_prefixだけを設定して
テストを実行してみました。

結果→×

やはりrakeがテスト用DBにデータをコピーするときにprefixを二重にしてしまいます。
こんなことでいいのか?>Rails
自分で修正できるものならしたいのですが,まだそこまでコードが分かりません。

25 Oct, 2007 | General | | Andy | Leave comment - 0 -

テストの問題は

http://www.ruby-forum.com/topic/169
とかにあるらしいことが分かってきました。
まだちゃんと理解していないけど,面倒そうだなあ…
set_table_nameとunit testとかで検索すると一杯でてくるので
既出のことのはずだけど,解決法がまとまっていないのは
いかがなものか,という気がします。

23 Oct, 2007 | General | | Andy | Leave comment - 0 -

新たな問題──先に進まないよう

やっとテーブル名の問題が解決したので(と思って),今度はモデルのリレーションを設定してみました。この部分はscaffoldではテストできないので,Railsのテスト機能を使ってみることに。

本を読むと,Rakeを使ったRailsのテスト機能ではテーブルをテスト用DBにコピーして使うとのこと。なるほど,それでテスト用DBは別の設定にしろと書いてあるわけです。新しくDBを作って実行してみました…

うまくいきません。テーブルがないと怒られます。

MySQL AdministratorでDBを見てみたところ,本来nucleus_itemなどとなるテーブル名が,nucleus_nucleus_itemなどとなっています。どうやら昨日の変更による副作用です。テーブルをコピーする際に,ActiveRecord::Base.table_name_prefixの設定を使って二重にプリフィクスを付けてしまったのでしょう。

しょうがないので,ActiveRecord::Base.table_name_prefixを使わず,プリフィクスを直打ちするという,なんともきたない方法で当座をしのぐことにしました。はぁ。

21 Oct, 2007 | General | | Andy | Leave comment - 0 -

問題解決

方向性は合っていました。インスタンス・メソッドではなく,クラス・メソッドにしなきゃいけないことに気付いて解決。YAMLを使うところには行き着いていませんが,そこはちょっとしきいが高そうなので,とりあえずこれで満足です。ちょっとRubyらしいことをした気分(笑)。

module ActiveRecord
  class Base
    def self.set_base_name(basename)
      @base_name = basename
    end
    
    def self.table_name
      @@table_name_prefix + @base_name.to_s
    end
  end
end



20 Oct, 2007 | General | | Andy | Leave comment - 0 -

結局難航

テーブル名にプレフィクスを付ける件,environment.rbの中でActiveRecord::Base.table_name_prefixを設定すればいいと書いてあったので試したところ,見事に動きませんでした。

いろいろ調べて分かったことはActiveRecord::Baseクラスの中で,モデルのクラス名からテーブル名を生成するtable_nameメソッドの中で,このプレフィクスが使われているということ。それに対して先日モデル・クラスの設定で行ったset_table_nameというのは,このメソッドをオーバーライドするものだった,ということです。オーバーライドしちゃっているから,ActiveRecord::Base.table_name_prefixが働かなかったわけです。

ActiveRecord::Baseとモデルの間に別のクラスを作って対処しようかと思ったのですが,そうするとAptanaでクラスを生成するたびに,そこを書き換えなければならず,メンテ的にかなりいやな感じ。Rubyでは存在しているクラスのメソッドを置き換えられるので,それで対処できないか考えました。

environment.rbの中でActiveRecord::Base.table_name_prefixを設定するのは同じですが,このほかに,

class ActiveRecord::Base
def set_base_name(name)
@base_name = name
end

def table_name
@@table_name_prefix + @base_name
end
end
といった記述を加え,モデル・クラスでは
set_base_name :item
などと書いてみました。しかしこれはset_base_nameがないというエラーになります。う~ん,environment.rbを先に見てくれないのか,それとも書き方の問題か。またストップしてしまいました。

PS. このブログのRSSを購読している人が何人かいるのですが,だれだろう。ちょっと気になります。

19 Oct, 2007 | General | | Andy | Leave comment - 2 -

DRYの呪縛に会う

Railsの精神としてDRY(Don't Repeat Yourself)というのがあります。要は車輪の再発明はするな,ということですね。これがRailsを便利にしているのは確かですが,半面,僕のような初心者にとっては,どれが既に存在しているものなのかが分からず,苦労する面もあります。さらにRailsの場合,規約が多いので,どこでどうなっているのか分かりにくいという面もあるような。

例えば,昨日からテーブルのプレフィクスをどうやって付けるのがいいのか,調べていたのですが,なかなか分かりませんでした。英語のフォーラムなども検索して,いくつか候補はでてきましたが,まだ試していないので,どれがいいのか分かりません。

あまり気にする必要はないのかもしれませんが,意外とラーニング・カーブは緩やかなのではないかという気がします。どこかでスレッショルドを超えると急に楽になるのでしょうけど。


18 Oct, 2007 | General | | Andy | Leave comment - 0 -

Railsにちょっと進出(やっと)

DBの文字コード問題が解決したのでやっと先に進めます。
まずはAptanaでアプリケーションを生成し,database.ymlを編集。移行したDBにアクセスするようにしました。注意したのはテーブル名を複数形にしない設定にしたこと。あと,テストモードのDBを別にしないといけないと注意書きが書いてありましたが,作るのが面倒なのでいまのところ一緒のものに。このあたりは問題が実際に起こってから考えます。
Railsはいろいろな「規約」を設けることで,プログラミングを楽にしていますが,実は今回のように既存のDBを使う場合,「規約」に合わせることができないため,いろいろと面倒なことが起こります。一からRailsで作るのと比べると倍くらい,気を使うところが多いのではないでしょうか。
次に,DBのテーブルにアクセスするための「モデル」を作っていきます。最初はモデルのクラスをただ作ればいいのかと思ったのですが,それだけでは動かないようです。generatorでモデルを作る必要がありました(このあたり,何がどう絡んで動いているのかは,知らなくてもいいのかもしれませんが,多分将来はきちんと理解しておく必要が出てくるでしょう)。
まずはアイテムのためのItemを生成。ここでもテーブルが規約に合っていないので,
set_primary_key: inumber
set_table_name: nucleus_item
と付ける必要があります。

とりあえず,scaffoldを使ってDBアクセスできるかどうか試そうとしたのですが,ジェネレータがDBがないとエラーを吐いてうまくいきません。CodeZineの記事を参考にコントローラを作り,scaffold: itemと書いてサーバーを起動。http://localhost/userにアクセスしたら,おお,ちゃんとnucleus_itemテーブルの内容が表示されました。

ただ,日本語が全部文字化けして?になっています。再びCodeZineの記事から文字設定をし(Layoutはまだ使っていないので不要),DBの文字設定もしました。多分DBのところが一番問題だったのではないかという気がします。これらの修正で,ちゃんと日本語でテーブルの内容を表示しました。

scaffoldには実用的な意味はあまり期待していないのですが,こうやってDBへのアクセスを簡単に確認できるのはありがたいことです。

というわけでRailsに踏み出したといっても,まだコードも何も書いていないのですが,一つ動くことはようやく確認できました。次はほかのテーブルも同じようにモデルを作っていき,リレーションの設定をしていくことになります。

17 Oct, 2007 | General | | Andy | Leave comment - 0 -

ようやくスタート地点に立つ準備が

鬱陶しかったMySQLの文字化け問題,結局Nucleusで取ったバックアップをUTF-8に設定したローカルのMySQL(XAMPP上)でリストア。それをMySQL Administratorでバックアップし,InstantRailsの上のMySQLにリストアすることで文字化けなしのDBになりました。

あー,めんどくさい。

こんなまだるっこしいことしなくていいのに,と思う人もいるでしょうが,XAMPPの環境やInstantRailsの環境をいじるのを避けようとすると,これくらいしか道がなくて。

それにしても将来ホスティングのDBでこの問題を解決しないといけなくなったら結構大変だなあ。

何か楽な手はないでしょうかねえ。

13 Oct, 2007 | General | | Andy | Leave comment - 0 -

My First Ruby Program

結局仕事で必要になったCSVの処理プログラムを作ることにした。
CSVを処理するライブラリがあったので,簡単にできそうだったというのがやっと飛び込んだ理由。
昨日ヘルプのWindows Help版をダウンロードしたのも気持ち的には大きい。やはりHelpは偉大だ。PHPもほとんどHelpで勉強したようなものだけど,これで高い文法本やライブラリ本を買わずに済んだ。

処理的には,HTTP使ってHTML取得したり,正規表現や文字列処理,例外処理も入って,わずか40行あまりながら,少し慣れた気がする。少なくともPerlの代わりにコマンドライン・ツールとして使うのはできそう。

03 Oct, 2007 | General | | Andy | Leave comment - 0 -

慣れたツールというのは楽なもので

MixiAddDiaryのところをRubyで書いてみようかと思ったけど
結局,ライブラリとかを調べるのが面倒なので,既に存在する
コードをいじるのがやっぱり一番楽だった。

仕事でちょっとテキスト処理をしないといけないのだけど,
これもローカルにサーバー立ててPHPで動かしてしまうのが
一番早く終わりそう。

本当はこういうところが新しいものにチャレンジするチャンス
なのだろうけど,やはり新しいものに踏み出すのは難しい。

特にライブラリがからむとそういう面が強くなる。

02 Oct, 2007 | General | | Andy | Leave comment - 0 -

難航してます

といってもプログラミングにはまだまだ入っていません。
とりあえずDBがないとどうしようもないので,今のブログのデータを
移行させたのですが,phpMyAdminでバックアップを取ったデータは
MySQL Administratorではリストアできないとかで,悩みました。

結局MySQL Administratorで直接リモートのサーバーにアクセスして
バックアップを取り,ローカルでリストアしたのですが,MySQLの
文字コード(リモート側)がLatin1になっているので文字化けしまくっています。気持ち悪いからここを修正して全部UTF-8で扱える
ようにしてから先に進みたいなあと。

何やってるんだか。


01 Oct, 2007 | General | | Andy | Leave comment - 0 -

© 2007 yoursite.com | Designed by DesignsByDarren
Ported to Nucleus CMS: Suvoroff