Rails tips vol2
最近Railsを触っていていろいろ知ったことをメモ。
コントローラから部分テンプレートのみを render したい場合
状況としては、Ajaxのレスポンスとしてある程度複雑なhtmlをテンプレートから生成し、かつ layout の application.html.erb を含めたくない場合。render :partial を使えば良い。
render :partial => 'tasklist', :locals => {:tasks => @tasks}
部分テンプレートへの引数は :locals => で渡す事もできる。
明示的に渡さなくても部分テンプレート内で @tasks でアクセスしてれば省略可能。
余談だけど、部分テンプレートに引数を渡すか、@val でグローバルっぽくアクセスするかの判断基準でいつも迷う。その部分テンプレートがどのくらい共通で使われているかにも寄るのかな。ポリシー決めないと複数人で開発する際に迷いそう。
日本語のパラメータをモデルで検索用に変換する
パラメータで日本語文字を受け取って、モデルで検索をかけたい場合、そのまま where に入れてもエンコードされているためヒットしない。そこで、モデルで検索パラメータとして使う前に URI.decode() する
where("name = ? and status = ? and msg LIKE ?", name , StatusTable[status] , "%#{URI.decode(filter)}%")
- filter がパラメータで受け取った日本語検索対象文字列
- LIKE で検索対象文字列を含むモデルインスタンスを抽出している
Jsonでレスポンスを返す
Ajaxのレスポンスで js.erb でコントローラで生成したデータ群を特定の js メソッドに渡すだけのコードを書くくらいなら、 json で返してクライアント側で js 呼び出しに渡すのがスマートらしい。
json を使うには以下の2点に注意する。
Ajaxリクエスト時に dataType: "jsonp" を付加する
これをやらないとサーバから json を受け取ってもコールバックを呼んでくれない。
$.ajax({ type: "PUT", cache: false, url: "/tasks/" + id, data: request_str, dataType: "jsonp" //★ここ重要 });
render :json でレスポンスを返す
コントローラで json として返したいデータをハッシュで生成して render :json に渡す。
その json データを受け取って処理するクライアントサイドの javascript のメソッドを :callback として指定してあげる。
render :json => counts, :callback => 'updateCounts'
devise で rspec のテスト
ユーザ認証機能付加してくれるプラグイン devise はとても便利なんだけど、フィルターに適用するとコントローラはそれまでの rspec が通らなくなってしまう。
あらかじめあるユーザでログインした状態でコントローラのテストを行いたい場合は以下のようにする。
- https://github.com/plataformatec/deviseを参考に以下を追加。
# spec/support/devise.rb RSpec.configure do |config| config.include Devise::TestHelpers, :type => :controller end
- テストコードでは sign_in するコードを追加する。
describe "GET 'index'" do it "レスポンスが正常であること" do sign_in User.first get 'index' response.should be_success end end