【Ruby on Rails】Atomフィードの実装
■まずXMLファイルを生成する方法として、大きく分けて2つの方法がある。
- 動的に生成する。(.rxmlファイルを使う)
- 静的に生成する。(cronなどを使って、メソッドが実行されたと時にファイルを生成する)
今回はそれぞれについて、まとめていく。
■動的に生成する。
1. まず以下のサンプルを参考に、rxmlファイルを作る。
●sample_feed.rxml
xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8" xml.feed('xmlns' => 'http://www.w3.org/2005/Atom') do xml.title @feed_title xml.subtitle @feed_subtitle xml.link "href" => (request.protocol + request.host_with_port + url_for(:rss => nil)), "rel" => "self","type" => "application/atom+xml" xml.author @feed_author xml.id @feed_id xml.updated Time.now @events.each do |ev| xml.entry do xml.title ev.title xml.link "href" => (request.protocol + request.host_with_port + url_for(:controller => 'hoge', :action =>'foge')) xml.id ev.id xml.updated ev.update xml.summary ({:type => "text/html", :mode => "escaped"}, ev.summary) end end end
2. 次にcontrollerでインスタンス変数とheaders["Content-Type"]を渡します。
※ここでheaders["Content-Type"]を指定することで生成するviewのフォーマットを指定出来ます。デフォルトは"text/html"。
●sample.rb
def sample_feed @feed_title = "sample" @feed_subtitle = "sub" @feed_author = "sample" @feed_id = "sample_id" @events = 動的に生成 headers["Content-Type"] = "text/xml; charset=UTF-8" render :layout => false end
■静的に生成する。-cronの利用
- 今回作る機能では、動的に実装してしまうと一定期間データがなくて不具合が起きてしまうため、静的に実装し直すことにした。
- Modelに機能を実装して、Cronを利用することで毎日一定時間にそのメソッドを実行する。
- Modelでは機能毎に細かく4つのメソッドに分けた。
以下にサンプルを記述します。
●sample_rss.rb
def self.header {:title => XML_TITLE, :subtitle => XML_SUBTITLE, :author => XML_AUTHOR, :id => XML_ID, :updated => Time.now.strftime("%Y-%m-%d %H:%M"), :link => XML_LINK } end def self.entries events = Event.find(:all, conditions =>["条件"]) entries = [] events.each do |event| entries << {:title => "#{event.title}", :link => "#{event.link}, :published => "#{event.published}", :updated => "#{event.updated_at}", :id => "#{event.id}", :summary => "#{event.summary}" } end entries end def self.create_atom(header ={}, entries = []) xml = Builder::XmlMarkup.new xmlobj = xml.feed("version" => "1.0", "xmlns" => "http://www.w3.org/2005/Atom", "encoding" => "UTF-8") do xml.title header.values_at(:title) xml.link({:type => "application/atom+xml", :href => header.values_at(:link)}) xml.subtitle header.values_at(:subtitle) xml.author header.values_at(:author) xml.id header.values_at(:id) xml.updated header.values_at(:updated) entries.each do |en| xml.entry do xml.title en.values_at(:title) xml.link({:href => en.values_at(:link)}) xml.published en.values_at(:published) xml.updated en.values_at(:updated) xml.id en.values_at(:id) xml.summary({:type => "text/html", :mode => "escaped"}, en.values_at(:summary)) # {:type => "text/html", :mode => "escaped"}これの指定で、summary要素の中で、 # HTMLタグが利用できるようになる。 end end end xml end def create_atom_file out_file_name = "#{RAILS_ROOT}/public/xml/#{XML_FILE_NAME}" #保存するXMLファイルの場所を指定 xml = self.create_atom(self.header, self.entries) file = File.open(out_file_name, 'w') file.puts xml.to_s.sub!(/<to_s\/>/, "") #to_sで配列を文字列に変換 & sub!(/<to_s\/>/, "")で"to_s"を空白に置換。 file.close #send_ping ←ping送信についてはまた後日まとめます。 self.send_ping_for_date end
- あとはcronを回して一定時間で"SampleRss.create_atom_file"を実行すればOK!!
■Cronの設定-今回はscript/runnerを利用した。
ruby script/runner "SampleRss.create_atom_file"
- cronで定期起動する。
0 0 * * * ruby /home/napzak/foo/script/runner "SampleRss.create_atom_file"
※cronの時間設定については以下を参照。
⇒http://d.hatena.ne.jp/satake7/20080615/p1
- ちなみに引数を渡すことも出来ちゃう。
ruby script/runner "SampleRss.create_atom_file(123)" ruby script/runner "SampleRss.create_atom_file 123"
★結論
実装にはかなり時間がかかりましたが、まとめてみると案外シンプルなものでした。。
やはり実装に取り掛かる前に徹底的な情報収集をする必要がありますね!
最後までお読み頂き、ありがとうございました。