40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

032-undefined method `bytesize' for xxxxにはまる

JSON形式の出力は単に

object.to_json

でOKというのを知って、

「おー、これならあっという間にできるなあ」

と思ってapp.rbに

get '/api/:name.json' do
  blogger = params[:name]
  @items = Entry.find(:conditions => {:blogger => blogger})
  @items.each do |item|
    content_type :json
    item.to_json
  end
end

を追加して実行すると

NoMethodError at /api/oyamada.json
undefined method `bytesize' for #

と怒られた。

問題の切り分けのためにSinatra使わない方法を確認

Sinatraを使わず、単にCUI上で表示するだけのプログラムを下記のように書いてみました。

require 'rubygems'
require 'mongoid'
require 'json'
Mongoid.configure do |config|
  name = "test"
  host = "localhost"
  config.master = Mongo::Connection.new.db(name)
  config.slaves = [
    Mongo::Connection.new(host, 27017, :slave_ok => true).db(name)
  ]
  config.persist_in_safe_mode = false
end

class Entry
  include Mongoid::Document
  field :blogger
  field :permalink
  field :title
  field :html_body
end

blogger_list = ['oyamada']
blogger_list.each do |blogger|
  items = Entry.find(:conditions => {:blogger => blogger})
  items.each do |item|
    puts item.to_json
  end
end

こちらは問題なく表示出来るので、どうもSinatraを使った時の書き方をどこか間違えているようでした。

こんな時はGoogle先生に聞いてみるのが一番かなと思って

sinatra undefined method `bytesize'」

で検索したらstackoverflowのページがヒットして、自分がはまっている問題と同じような感じがしたので、下記のようにコードを変更しました

get '/api/:name.json' do
  blogger = params[:name]
  body = ''
  @items = Entry.find(:conditions => {:blogger => blogger})
  @items.each do |item|
    content_type :json
    body << item.to_json
  end
  body
end

これで無事JSON形式で出力できたー。

今後にむけて現時点の状況を整理

  • ブロガー別の更新情報を取得→crwaler.rb実装済(ただしどこまで情報取得したのかを管理する処理が未実装)
  • /api/xxx.jsonのような形で、ブロガー別の更新情報をJSON形式で取得→Sinatraのapp.rbで実装済

という感じで、自分の中ではちょっとゴールが見えてきました。

Herokuにアップして、iPhone側から利用出来るか確認しよう