assaulter's diary

主にバイクについて

Vagrant+Chef-soloでplay frameworkが動くところまで作ってみた

Amazon.co.jp: 入門Chef Solo - Infrastructure as Code eBook: 伊藤直也: Kindleストア

をひと通り読んだので、習作として、play! frameworkが動作可能な環境をvagrant上のcentOSに構築するchef-soloを書いてみたので公開します。

https://github.com/assaulter/vagrant-play

ポイントとしては、vagrant up一発で起動するのではなく、ちゃんとcookbookを取得してきてknifeで料理するところをコマンド打たせるところかなー()

計6発叩かないといけないのと、Vagrantfileおよびvagrant pluginでコマンドを省略できるのは知ってるので、次回はコマンドを短縮するところをやろうと思います。

RailsでAPIサーバー用プロジェクトを作成する

仕様

タスクをjson形式でやりとりする。

API

タスク一覧:GET /tasks
タスク(個別):GET /tasks/:id
タスク登録:POST /tasks
タスク更新:PATCH /tasks/:id
削除:DELETE /tasks/:id

Rails-API Gemを使ってプロジェクトを作成する

rails-api/rails-api · GitHub

こちらを仕様すると、View周りのassets等が排除されたシンプルなRailsプロジェクトが作成されます。

View周りはMV*なJSのフレームワークに任せるっていうの、最近流行ってるんですかね?

gem を追加する
gem install rails-api

rails-apiを用いてプロジェクトを作成する
rails-api new todo_api

好みに応じて、Gemfileを編集し、bundle installする。

僕はテスト用にfactory_girl_rails, rspec, rspec-railsを追加しました。

テーブル作成
rails g scaffold task name:string
rake db:migrate

これでコントローラも作成されます。というかこの時点で

Chrome Web Store - Advanced REST client

等を使って叩くと動きますw

あとは

# create時にpostされたパラメータに対して適用するメソッド
def task_params
  allow = [:name]
  params.require(:task).permit(allow)
end

# POST /tasks
# POST /tasks.json
# params example
# {"task":
#   {"name": "sample"}
# }
def create
  @task = Task.new(task_params)

  if @task.save
    render json: @task, status: :created, location: @task
  else
    render json: @task.errors, status: :unprocessable_entity
  end
end

一応ガードをかけておきます。

次はFactory girlを使ったRSpecの書き方かな・・・

AngularJSのプロジェクトを共有する

前回の記事で作成したAngularJSのプロジェクトの共有方法について。

デフォルトで.gitignoreがついてくるので、そのまま適当なgitサーバーに追加。 そのプロジェクトをくろーんしてきた人のやることについて。

npm install
...
...
bower install
...
...
grunt
...
...

これで必要な物件は揃うので、grunt serverで起動。楽ですね。

ちなみに

npmはpackage.json、bowerはbower.jsonを利用します。

また、Gruntfile.jsには、起動時に実行するスクリプトや、監視対象のファイルのパス(ファイルに変更があると登録されているイベントが発火、JSHintを実行する等)が書かれてます。

AngularJSのプロジェクトを作成する

チュートリアルを終え、さてToDoアプリでも作りますかと思ったが、プロジェクトどうやって作るんだろうと思ったので、調べた結果をメモしておきます。

Nodeの環境

そもそものNodeの環境も、nodebrewってのがあるので入れました。

入れ方は下記を参照。

hokaccha/nodebrew · GitHub

AngularJS generator

yeoman/generator-angular · GitHub

こいつを使います。読み方はヨーマンですかね。

YeomanでAngularJSのテンプレートを作成する

yo angular [app-name]

を実行すると、SassとTwitterBootstrapを使うかどうか、あとは4つばかしのモジュールを入れるかどうかを聞かれるので適当に。

他にもrakeコマンドっぽく、コントローラーの作成等も出来るみたいなので、それはおいおい。

Rubyでインスタンスに対して固有のメソッドを定義する

テスト時に、特定のメソッドが実行されているかどうかを確認したい時に、こういう方法を使ったのでメモ。

要件

private な send_mail メソッドが、実行されていることをRSpecで確認したい。

ベースとなるクラス

class Some
  def execute
    # 状況に応じてsend_mailを実行したり、しなかったりする
  end
  
  private 
  
  def send_mail
    # メールが送信される的な
  end
end

RSpec内の記述

it 'send_mailメソッドが実行されること' do
  some = Some.new
  class << some
    # someの特異クラス内
    attr_accessor :is_executed
    def send_mail
      @is_executed = true
    end
  end

  some.execute
  expect(some.is_executed).to be_true
end

局所的にやるんだったら上記の記述でおkですが、複数同じことやるんだったらこんな感じにもできます。

module SendMailChecker
  attr_accessor :is_executed
    def send_mail
      @is_executed = true
    end
end

it 'send_mailが実行されること' do
  some = Some.new
  some.extend(SendMailChecker)
  
  some.execute
  expect(some.is_executed).to be_true
end

オブジェクト.extendしてあげると、オブジェクトの特異クラスにモジュールを取り込むことになるので、先ほどの書き方と一緒になるというわけです。

参考:Ruby7不思議 - 特異クラス・特異メソッド・クラスメソッド - basyura's blog

Rubyで大文字小文字を無視した検索

配列に対して、特定の文字列が含まれるかどうかを調べる際には、こんな感じにしますよね?

%w(test sample code).include?('test')

この場合、testに完全に一致しないとtrueを返してくれないので、大文字小文字を無視して検索したい場合にはこんな感じですかね。

%w(test sample code).find{|item| item =~ /^test$/i}.nil?.!

ちなみに、railsで使うんだったら、nil?.!の部分がpresent?でいいと思います。

日本で一番簡単にビットコインが買える取引所 coincheck bitcoin

Rubyで簡易ストラテジー

いい感じに慣れてきたので、Rubyに関するメモを残していこうと思います。

簡易ストラテジーの実装

異なるkeyを渡した場合に、一部のメソッドの動作を変更したい場合を想定。

class SearchClass
  module IdSearchRequest
    def self.request(value)
      # keyがIDの場合のリクエストを返却
    end
  end

  module NameSearchRequest
    def self.request(value)
      # keyがNAMEの場合のリクエストを返却
    end
  end

  MODULE_BY_KEY = {
    id: IdSearchRequest,
    name: NameSearchRequest
  }
  
  def search(key, value)
    request = MODULE_BY_KEY[key.to_sym]::request(value)
    # リクエストオブジェクトを使って検索を実行
  end
end

JavaとかだとEnumを使って実装するんでしょうが、Rubyで実装する場合はこんな感じですかね。

ちなみに、モジュールにインスタンス変数を持たせたい場合は、モジュールを取ってきてclass.eval等でincludeする方法も結構使ってます。