-
Wavesを試してみる - Model編 2008-03-15 14:51:44
引き続きWavesを試してみます。
チュートリアルによると、entryに1:nでcommentモデルとの関連付けをしています。
まずはCommentsテーブルのmigrationを作成します。rake schema:migration name=add_comments
で、schema/migrations/002_add_comments.rbを編集。
class AddComments < Sequel::Migration def up create_table :comments do primary_key :id foreign_key :entry_id, :table => :entries text :name text :email text :content timestamp :created_on end end def down drop_table :comments end endそういえば、RailsではDBレベルでforeign_keyをあまりつけてないな。あと、created_onはSequelによって自動的に時刻が入るよう。Railsでいうcreated_atだね。created_onだと日付しか入らないみたいな感じがしてしまうのは、Railsの使いすぎか。ちなみにSequelというのはORMです。
migrateをかましたら、Entryモデルを作成します。ていうか、今まで存在しなかったのかよ。デフォルトの動作がWavesの中で定義されていて、それ以外のことをやりたくなったときにはじめてコードを書くのかな。rake generate:model name=entry
で、models/entry.rbが作成される。
module Blog module Models class Entry < Sequel::Model(:entries) before_save do set(:updated_on => Time.now) if columns.include? :updated_on end end end endbefore_saveはRailsと一緒かな。テーブルがupdated_onを持っていたら更新してくれるみたい。created_onはSequelでやってくれるのに、updated_onは自前でやるのか。中途半端だなあ。Wavesが勝手にコード吐いてくれるけど。
で、models/default.rbの中身がこれと一緒になっている。明示的にモデルを作成しなかったときは、default.rbが使われるんだな。たぶん。
さて、models/entry.rbにcommentmモデルとの関連付けを定義しましょう。one_to_many :comments, :from => Blog::Models::Comment, :key => :entry_id
こいつをbefore_saveの下に追加します。Railsでいうところのhas_manyと一緒だね。相手のモデルと参照キーを指定してやんないといけない。fromって、なんだかぼくの認識だと参照先みたいな感じがしてしまう。
つづいてcommentモデルを作成する。rake generate:model name=comment
models/comment.rbは
module Blog module Models class Comment < Sequel::Model(:comments) before_save do set(:updated_on => Time.now) if columns.include? :updated_on end one_to_one :entry, :from => Blog::Models::Entry end end endone_to_oneはRailsでいうbelongs_toだな。ここでのfromは違和感がない。
さて、viewのほうにコメントを追加してみます。チュートリアルからちょっとアレンジしてみます。templates/entry/show.mabは
layout :default, :title => @entry.title do a "すべて見る", :href => '/entries' h1 @entry.title textile @entry.content h2 "コメント" view :comment, :add, :entry => @entry view :comment, :list, :comments => @entry.comments end
こんな感じ。見てわかるように、@entry.commentsみたいな感じでAR的にリレーション先へアクセスできるようです。
さて、add.mabとlist.mabをtemplates/commentディレクトリ下に作ります。
templates/comment/add.mabform :action => "/comments", :method => 'POST' do input :type => :hidden, :name => 'comment.entry_id', :value => @entry.id label "名前"; br input :type => :text, :name => 'comment.name'; br label "Email"; br input :type => :text, :name => 'comment.email'; br label "コメント"; br textarea :name => 'comment.content', :rows => 10, :cols => 80; br input :type => :submit, :value => "書き込み" end
POST先のURLが/commentsになっている。RailsみたいなURL(/entries/:id/comments)じゃないね。かわりに、hidden fieldを持っていて、そこにentry_idを入れている。これだと、URLはシンプルになっていいかも。REST的にはRailsの方が正しい気もするんだけど。
それから、templates/comment/list.mab@comments.sort_by( &:created_on ).each do |comment| name = ((comment.name.nil? or comment.name.empty?) ? "通りすがり" : comment.name) p %Q|#{name} #{comment.created_on.strftime("%Y-%m-%d %H:%M")}| textile comment.content endチュートリアルのコードはわかりにくくて好きじゃない感じだったので書き直してみました。
で、実際にコメントを書いてみると、/comment//editorなんていうURLに飛ばされるのだけど、当然404になる。いよいよルーティングを定義する必要があるみたい。続きはまた今度にしよう。
-
テーブルにインデックスをはると、insertの速度が遅くなる 2008-03-15 15:00:42
と思っていたんだけど、実際のところはそんなに変化しなかった。innoDBだからなのかなあ。と思っていたら、500万以上のレコードを insert into ... select.. で一度にインサートしようとしたら極端に遅くなった。O(n^2)な感じなのかな。
-
後部文字列を取り出すtruncateを書く 2008-03-15 16:48:19
milookのリニューアル作業をしていて、文字列の後部を取り出す必要が出てきたのですが、truncateは前部しか取り出せません。なので、自分で作りました。
config/environment.rbmodule ActionView module Helpers module TextHelper def truncate_with_back(text, length = 30, truncate_string = "...") if length >= 0 truncate_without_back(text, length, truncate_string) else return if text.blank? text.chars.length > -length ? "#{truncate_string}#{text.chars[length..-1]}" : text end end alias_method_chain :truncate, :back end end end

コメント(
リンク元(27)
