Skip to content

Instantly share code, notes, and snippets.

@gaaamii
Last active January 6, 2016 23:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaaamii/1d45744433eae3e29f08 to your computer and use it in GitHub Desktop.
Save gaaamii/1d45744433eae3e29f08 to your computer and use it in GitHub Desktop.
2015/12/29 iOSアプリにJSONデータ返してもらうための Ruby on Rails 入門

To @ToraDady

そんなの知ってるわ、それは違うわ、という部分あったら指摘下さい。

Ruby on RailsのアプリケーションでJSONデータを返す方法などを調べつつ書いていきます。

BaaS vs Ruby on Rails

iOS開発のバックエンドが欲しい、iPhoneからサーバーとデータのやり取りをしたいという場合は、自前でウェブアプリを構築する以外の方法もあります。それがBaaS(Backend as a Service)です。BaaSは、クライアント(iOSのようなモバイルやデスクトップアプリなど)のバックエンドを提供してくれるサービスの総称で、有名どころではParseFirebaseなどがあります。

すでにRailsアプリがあって、そのモバイルアプリが欲しいという流れでiOS開発を検討しているならわざわざBaaSに乗り換える必要はなさそうですが、一からiOSアプリをつくる&そのバックエンドが欲しい、という場合には、BaaSとRailsどっちがいいのか、というのは考えてみる価値がありそうです。BaaS vs Ruby on Railsで検索してみると、こういう質問が出てきたりします。

iOSエンジニアが一からRailsを覚えるのはけっこう大変なことだと思うので、目的によってはBaaSのようなものも使えるというのを知っておくといいかもしれません。

とは言ったものの、僕はモバイルアプリのバックエンドとしてBaaSを使ったことがない(そもそもモバイルアプリ開発経験がない)ので、なんとも言えません。Railsのいいところに関して言うと、データの管理や提供方法を自分で決められるというところでしょうか。BaaSはあくまでもParseやFirebaseなどが提供するAPIを通じてデータのやり取りをすることになると思いますので、できることが限定されるはずです。

Getting Started

AWSは難しい(僕がよくわからない)ので、Herokuを使ってRailsアプリをデプロイするのが良さそうです。Herokuにデプロイする際に使うものは、Herokuアカウント・Herokuツールベルト・gitの3つになるかと思います。

まずgitは何かと言われたら、通常はバージョン管理ツールと答えるのが正しいです。しかし、Herokuを使う場合にはデプロイツールとしての役割も持つことになります。git自体はすでに(僕なんかよりも詳しく)ご存知だったりするかもしれないので、gitそのものについての説明は省いて、RailsアプリをHerokuにデプロイする流れを書きます。

...と思ったんですけど、HerokuのDocumentation読んだほうがよっぽどわかりやすいような気がしてきたのでそちらを貼ります。

Railsアプリ

JSONデータを返すRailsアプリを構築する時に最低限何をするかというのを説明するために、ここではブログ記事のモデルのみが存在するアプリを作ってみます。

プロジェクト作成

rails new json_server

雛形生成とデータベース初期化

railsのgenerateコマンドを使って雛形を生成して、データベースを初期化します。

bin/rails generate model Post title:string body:text
bin/rails generate controller Posts
bin/rake db:migrate

Bundler と Rubygems

Cocoapods使ってると思うのでたぶん大丈夫だと思います。

プロジェクトで利用するライブラリのバージョンなどは、Gemfileに記載していきます。rails newでプロジェクトを作成すれば、すでに以下の様なGemfileが作られているはずです。

source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.5'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
...

このGemfileが置かれたところで、bundle installをすればライブラリが読み込まれます。

bundle install --path vendor/bundle

--pathvendor/bundle というパスを渡して、gemのインストール場所を指定しています。

ルーティング

ルーティング(「このURLへのリクエストはこのコントローラを呼び出す」という設定)は config/routes.rbに書きます。

Rails.application.routes.draw do
  resources :posts
end

とりあえずこれだけで十分です。このルーティングは、Postというモデル・PostsControllerというコントローラがある前提で書かれます。以下を実行します。

bin/rake routes

出力結果を見ると、どのURIパターンに何というメソッドが割り当てられているかがわかります。

   Prefix Verb   URI Pattern               Controller#Action
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

コントローラ

先ほどの bin/rake routes で見た通り、このアプリケーションの/postsというパスに対応するのはPostsController#indexになります(※Rubyのドキュメントではよく、クラス名#インスタンスメソッド名という記述をします)。

とりあえず、index(一覧)とshow(詳細)のコントローラを作ります。

class PostsController
  def index
    @posts = Post.limit(20)
    render json: @posts
  end
  
  def show
    @post = Post.find(params[:id])
    render json: @post
  end
end

データを挿入する(コンソールから)

Railsにはconsoleというコマンドオプションがあり、それを使えばRailsアプリの実行環境でいろんなことができます。

bin/rails console

ブログ記事を挿入しましょう。

irb(main):001:0> Post.create({title: "寿司食べた", body: "回転寿司安くてうまくて最高。ただ、うには回転寿司で食べるもんじゃないな。"})
   (0.0ms)  begin transaction
  SQL (0.6ms)  INSERT INTO "posts" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "寿司食べた"], ["body", "回転寿司安くてうまくて最高。ただ、うには回転寿司で食べるもんじゃないな。"], ["created_at", "2015-12-28 16:12:15.165223"], ["updated_at", "2015-12-28 16:12:15.165223"]]
   (1.3ms)  commit transaction
=> #<Post id: 1, title: "寿司食べた", body: "回転寿司安くてうまくて最高。ただ、うには回転寿司で食べるもんじゃないな。", created_at: "2015-12-28 16:12:15", updated_at: "2015-12-28 16:12:15">

これで、サンプルデータが入りました。このRailsアプリにアクセスした時に、JSONでデータが返ってくれば成功っぽいです。

アクセス

サーバーを立ち上げてみましょう。

bin/rails server

そしたら、アクセスしましょう。JSONのAPIを叩くって感じで、あえてブラウザではなくコマンドからいきます

curl localhost:3000/posts
[{"id":1,"title":"たいとる","body":"ぼでぃー","created_at":"2015-12-28T16:00:06.305Z","updated_at":"2015-12-28T16:00:06.305Z"}]

良いんじゃないでしょうか。

(JSONを返すための)View

モデルの属性値をそのまま出す場合だけじゃないと思います。そういうときは(TODO: どういうとき?)、JbuilderというDSLを使います。

(TODO: 良い感じのサンプル)

参考資料

@gaaamii
Copy link
Author

gaaamii commented Dec 29, 2015

bundle install 時にエラー

Installing pg 0.18.4 with native extensions

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb
checking for pg_config... no
No pg_config... trying anyway. If building fails, please try again with
 --with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
 --with-opt-dir
 --without-opt-dir
 --with-opt-include
 --without-opt-include=${opt-dir}/include
 --with-opt-lib
 --without-opt-lib=${opt-dir}/lib
 --with-make-prog
 --without-make-prog
 --srcdir=.
 --curdir
 --ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
 --with-pg
 --without-pg
 --enable-windows-cross
 --disable-windows-cross
 --with-pg-config
 --without-pg-config
 --with-pg_config
 --without-pg_config
 --with-pg-dir
 --without-pg-dir
 --with-pg-include
 --without-pg-include=${pg-dir}/include
 --with-pg-lib
 --without-pg-lib=${pg-dir}/

Gem files will remain installed in /Users/tac/Desktop/tac_json_server/vendor/bundle/ruby/2.0.0/gems/pg-0.18.4 for inspection.
Results logged to /Users/tac/Desktop/tac_json_server/vendor/bundle/ruby/2.0.0/gems/pg-0.18.4/ext/gem_make.out

@gaaamii
Copy link
Author

gaaamii commented Dec 29, 2015

rubyのバージョンは大丈夫

@gaaamii
Copy link
Author

gaaamii commented Dec 29, 2015

以下でうまくいった

ARCHFLAGS="-arch x86_64" bundle install

ので、.bashrc にARCHFLAGS書いとく

@gaaamii
Copy link
Author

gaaamii commented Dec 29, 2015

bin/rails generate model Post title:string body:text
/Users/tac/.rbenv/versions/2.2.4/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- bundler/setup (LoadError)
 from /Users/tac/.rbenv/versions/2.2.4/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
 from /Users/tac/Desktop/tac_json_server/config/boot.rb:3:in `<top (required)>'
 from bin/rails:3:in `require_relative'
 from bin/rails:3:in `<main>'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment