Rails3.1.rc4 と sprockets 2.0.0.beta.11 は相性が悪く

/assets/以下のルーティングに失敗してしまうので

Gemfileで下記のようにする

gem 'sprockets', '!= 2.0.0.beta.11'
Posted in ruby, ruby on rails at 7月 14th, 2011. No Comments.

Railsのコントローラーで、ステータスコードを返すときは

head 200

のように、ステータスコードの数字で返すこともできますが

head :ok

のように、数字の代わりにシンボルを使うこともできます。

しかしRailsのリファレンスを眺めていても :ok 以外のシンボル名がわからなかったので調べてまとめました。

参考:http://rubydoc.info/gems/rack/1.2.1/Rack/Utils

# 確認方法
Rack::Utils.status_code(:bad_gateway) # => 502

ちなみに、辞書にないシンボルを渡すと問答無用で500を返します。ですから、500を返すときは

head :ng

と、やっています。

コード 名前 シンボル
100 Continue :continue
101 Switching Protocols :switching_protocols
102 Processing :processing
200 OK :ok
201 Created :created
202 Accepted :accepted
203 Non-Authoritative Information :non_authoritative_information
204 No Content :no_content
205 Reset Content :reset_content
206 Partial Content :partial_content
207 Multi-Status :multi_status
226 IM Used :im_used
300 Multiple Choices :multiple_choices
301 Moved Permanently :moved_permanently
302 Found :found
303 See Other :see_other
304 Not Modified :not_modified
305 Use Proxy :use_proxy
306 Reserved :reserved
307 Temporary Redirect :temporary_redirect
400 Bad Request :bad_request
401 Unauthorized :unauthorized
402 Payment Required :payment_required
403 Forbidden :forbidden
404 Not Found :not_found
405 Method Not Allowed :method_not_allowed
406 Not Acceptable :not_acceptable
407 Proxy Authentication Required :proxy_authentication_required
408 Request Timeout :request_timeout
409 Conflict :conflict
410 Gone :gone
411 Length Required :length_required
412 Precondition Failed :precondition_failed
413 Request Entity Too Large :request_entity_too_large
414 Request-URI Too Long :request_uri_too_long
415 Unsupported Media Type :unsupported_media_type
416 Requested Range Not Satisfiable :requested_range_not_satisfiable
417 Expectation Failed :expectation_failed
422 Unprocessable Entity :unprocessable_entity
423 Locked :locked
424 Failed Dependency :failed_dependency
426 Upgrade Required :upgrade_required
500 Internal Server Error :internal_server_error
501 Not Implemented :not_implemented
502 Bad Gateway :bad_gateway
503 Service Unavailable :service_unavailable
504 Gateway Timeout :gateway_timeout
505 HTTP Version Not Supported :http_version_not_supported
506 Variant Also Negotiates :variant_also_negotiates
507 Insufficient Storage :insufficient_storage
510 Not Extended :not_extended
Posted in ruby on rails at 6月 29th, 2011. No Comments.

冴えないタイトルですみません。メモです。

Cucumber + Capybara で RESTful APIをテストする場合は

シナリオ: コメント投稿APIからコメントを投稿できる
  もし  パラメーター "body" に "こんにちは!" を設定する
  かつ  "コメント投稿API"を"POST"で送信する
  ならば ステータスコードは "201" であること
もし /^パラメーター "([^"]*)" に "([^"]*)" を設定する$/ do |param_name, value|
  @params ||= {}
  @params.merge!({
    param_name.to_sym => value
  })
end

もし /^"([^"]*)"を"([^"]*)"で送信する$/ do |page_name, http_method|
  send(http_method.downcase.to_sym, path_to(page_name), @params)
end

ならば /^ステータスコードは "([^"]*)" であること$/ do |status_code|
  response.status.should eq(status_code.to_i)
end

こんな感じでテストを書いています。(「コメント投稿API」はpath.rbで定義しておきます)

さて、本題ですが画像のアップロードでハマりました。
ハマった仮定は省きますが、CapybaraがRack::Testをドライバーとして使っているので、Rack::Test::UploadFile を使ってファイルアップロード周りのコードを簡略化できます。

シナリオ: コメント投稿APIから画像付きのコメントを投稿できる
  もし  パラメーター "body" に "こんにちは!" を設定する
  かつ  パラメーター "image" に "sample.png" をファイルとして設定する
  かつ  "コメント投稿API"を"POST"で送信する
  ならば ステータスコードは "201" であること
もし /^パラメーター "([^"]*)" に "([^"]*)" をファイルとして設定する$/ do |param_name, file_path|
  file = File.new(File.join(Rails.root, 'features/fixtures/images' file_path))
  content_type = MIME::Types.type_for(file.path)[0].to_s
  @params ||= {}
  @params.merge!({
    param_name.to_sym => Rack::Test::UploadedFile.new(file.path, content_type)
  })
end

Rack::Test::UpoadFileの使い方などは、Rack::TestのRSpecを見るとわかりやすかったです。
https://github.com/brynary/rack-test/blob/master/spec/rack/test/multipart_spec.rb

Posted in ruby, ruby on rails at 2月 16th, 2011. No Comments.

メモです。

RailsでMongoidを試していろいろやっているのですが、SQLでGROUPとか使う系の処理は、Mongoidに備わっているgroupメソッドよりもmap_reduceメソッドの方が良さそうなのでした。

MapReduce
http://www.mongodb.org/display/DOCSJP/MapReduce#MapReduce-map%E3%83%95%E3%82%A1%E3%83%B3%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

map_reduce method in Class: Mongo::Collection
http://api.mongodb.org/ruby/current/Mongo/Collection.html#map_reduce-instance_method

例えばPointというコレクションがあって、ユーザーごとのポイントを集計してソートしたいという場合、以下のようなコードで集計&ソートできました。

m =<<-EOT
function(){
  emit(this.user_id, {
    point: this.point
  });
}
EOT

r =<<-EOT
function(key, values){
  var sum = 0;
  values.forEach(function(value){
    sum += value.point;
  });
  return {
    point: sum
  };
}
EOT
Point.collection.map_reduce(m,r).find.sort('value.point', :desc)

慣れればもっと複雑なことができるんだろうけど、mongodb自体よくわかってないので・・。

ここを参考にしました: MongoDB, Mongoid and Map/Reduce
http://nsaunders.wordpress.com/2010/08/09/mongodb-mongoid-and-mapreduce/

Posted in ruby, ruby on rails at 2月 13th, 2011. 2 Comments.

メモです。

非同期処理にResqueを使う場合、/resque にアクセスすることでResqueのジョブ管理画面を利用できます。

公開する場合、管理画面には認証をかけておきたいので、簡単にBasic認証をかけます。

Rails.root にあるconfig.ruを編集します。

require ::File.expand_path('../config/environment',  __FILE__)
require 'resque/server'
# run Rack::URLMap.new
#   "/"       => MyApp::Application,
#   "/resque" => Resque::Server.new

map '/' do
  run MyApp::Application
end

map '/resque' do
  use Rack::Auth::Basic do |user, passwd|
    user == 'admin' && passwd == 'passwd'
  end
  run Resque::Server.new
end%

これで「admin/passwd」で認証が掛かりました。

Rackって便利っすねー。

参考:http://akr97.com/capsule/?tag=ruby&paged=3

Posted in ruby, ruby on rails at 2月 4th, 2011. No Comments.

rspecで簡単にJSONの構造をテストしたい時に使えるTIPS

# spec/support/custom_matchers.rb
RSpec::Matchers.define :have_json do |selector|
  match do |response_body|
    selector.gsub!(/_/,'-')
    json = JSON.parse(response_body)
    prefix = case json
    when Array
      "/objects/object"
    when Hash
      "/hash"
    end
    doc = Nokogiri::XML(json.to_xml)
    doc.search(prefix + selector).size > 0
  end
end

have_jsonというカスタムマッチャを用意します。 JSONをXMLに変換し、nokogiriを使ってxpathで検索します。

# 試してないので動かないかも・・
# ex:response json
#  {
#    "hoge" :
#    {
#      "id" : 1,
#      "name" : "aaaaaa",
#      "body" : "bbbbbbbbbbbb",
#    }
#  }
describe HogesController
  context "GET /hoge/1.json"
    it "should have [:id, :name, :body] in response JSON" do
      get :show, :id => 1, :format => :json
      response.body.should have_json("/hoge/id")
      response.body.should have_json("/hoge/name")
      response.body.should have_json("/hoge/body")
    end
  end
end

サンプルはこんな感じ JSONの中身から、検索したいキーを、xpathで指定します。 キーが見つかれば、テストが通ります。

Posted in ruby at 1月 27th, 2011. No Comments.

(この記事はRuby Advent Calendar jp: 2010 : ATNDの12日目です。前日はbash0C7さんでした。)

今日はRubyでイケてる管理画面を生成する「Typus」を紹介します。

Typusは

  • デザインがシンプルで素敵
  • 認証機能つき(認証なし・HTTP認証・DB認証から選べます)
  • ユーザーの権限制御が可能
  • Rails3で動く
  • テンプレートのカスタマイズが楽

という点でイケてます。

Rails2からRails3になって、様々なプラグインの定番が切り替わった印象を受けていますが、TypusもActiveScaffoldに変わって定番になるだろうなぁと思うので、是非使ってみてください。

https://github.com/fesplugas/typus

用意

まずは、Rails3で簡単なプロジェクトを作ります。ユーザーモデルとタスクモデルを生成します。

% rails new todo
% cd todo
% rails generate model user username:string
% rails generate model task title:string completed:boolean user_id:integer
% rake db:migrate

準備OKです。

Gemfile編集

Gemfileにtypusを追加します。

gem 'typus', :git => 'https://github.com/fesplugas/typus.git'

Bundleを更新します。

% bundle
Fetching https://github.com/fesplugas/typus.gitremote: Counting objects: 36226, done.
remote: Compressing objects: 100% (13705/13705), done.
remote: Total 36226 (delta 21273), reused 35447 (delta 20675)
Receiving objects: 100% (36226/36226), 3.81 MiB | 428 KiB/s, done.
Resolving deltas: 100% (21273/21273), done.
Fetching source index for http://rubygems.org/
Using rake (0.8.7)
… 略
Using typus (3.0.3) from https://github.com/fesplugas/typus.git (at master)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

ジェネレーターを実行して、管理画面を生成する

% rails g typus
create  config/typus/README
create  config/initializers/typus.rb
create  config/initializers/typus_resources.rb
以下略

できあがり! イヤッホゥ、超簡単!

さらにカスタムしたいなら

ドキュメントを参考のこと http://core.typuscms.com/

Posted in ruby, ruby on rails, 日記 at 12月 12th, 2010. 1 Comment.

昨日、mixiの新プラットフォームの発表会、mixi meetup 2010 が行われ、僕も参加してきました。

mixiコネクトはmixi pluginとmixi graph api という2つに分かれました。

予想以上にmixiの本気を感じることができて、今後はmixiへの対応もどんどんとりいれていこうと思いました。

ので、帰ってきてさっそく本日から一般でも使えるようになったmixiチェックボタンをラペコに追加してみました。

こんな感じ

クリックするとポップアップが立ち上がり、 mixiのアクティビティに表示されて、マイミクにペコフォトをチェックしたことを知らせることができます。

どうぞ、チェックしてみてください。

Posted in ruby on rails, ラペコ at 9月 11th, 2010. No Comments.

Mitaka.rb #10 でLTをさせていただきました。

http://atnd.org/events/7542

ラペコについての紹介LTでした

Mitaka.rb主催者でもあり、今回LTのお誘いをいただいた@ysakaki さん、運営の方々、ありがとうございました。

Posted in ruby, 日記 at 9月 10th, 2010. No Comments.

Rails3で簡単なサンプルを作ってみた スレッド式掲示板です。

レスは追加できるけど、スレッド追加する機能は作り忘れた。

Mongoid版

http://github.com/func09/rails3_sample_bbs/tree/mongoid-20100813

ActiveRecord版

http://github.com/func09/rails3_sample_bbs/tree/activerecord-20100813

それぞれのREADMEに従えば動くはず。 rake db:seed でサンプルデータがインサートされるます。

Rails3だからといって、別段特殊なコードは書けなかった。 よくもわるくもいつもどおり書けた。

http://github.com/func09/rails3_sample_bbs/zipball/mongoid-20100813

http://github.com/func09/rails3_sample_bbs/zipball/activerecord-20100813

Posted in ruby, ruby on rails at 8月 16th, 2010. No Comments.