Ruby
Sinatra

ActiveRecordで取得したオブジェクトをハッシュに変換し、値がnullになっているキーを除外する

More than 3 years have passed since last update.

環境


  • ruby: 2.1.5
  • DB: sqlite3.6.20
  • Sinatra: 1.4.5

データベース


以下のように1つひとつのフィールドのどこにnullが入っているかわからない場合、
クエリでnull以外を取得しないようにしようと試みましたが、失敗に終わりました。
(もしもっと簡単にできる方法があれば教えて下さい・・・)

そこで、一度Hashとして受け取り、値がnullのkeyとvalueを削除し、jsonにして返すように方針を変えました。
id col1 col2 col3 col...
1 null hoge hogehoge null
2 hoge hogehoge null hogehogehoge
3 hoge null hogehoeg hogehogehoge
4 null hoge hogehoeg null

コード


/:id にアクセスし、該当するレコード1列の値が入っているもののみを返すことにします。
まずはルーティングから。モデル名はUserとします。
main.rb
get '/:id' do
  #findでidからレコードを取り出してjsonに
  user = User.find(params[:id]).to_json
  #jsonをハッシュにしてnullを除去
  hash = JSON.parse(user).compact!
  content_type :json , :charset 'utf-8'
  hash.to_json
end

続いて、上で呼び出したcompact!を書き加えます。

main.rb
class Hash
  def compact!
    delete_if{ |key, val| val.nil? }
  end
end

以上で、null以外が入ったレコードの取り出しができます。

追記: Rails(ActiveSupportが使える環境)の場合



@k-shogo さんがコメントで指摘してくれたように、Railsだと以下のように書くことができます。
get '/:id' do
  user = User.find(params[:id])
  hash = user.attributes.compact
  content_type :json , :charset 'utf-8'
  hash.to_json
end

厳密に言うと、attributesメソッドはActiveRecordで、compactはActiveSupportでそれぞれ用意されているメソッドになります。