Rails: Doorkeeperでのログイン処理中に起きたエラーをJSONで出力

Doorkeeperでログイン中にエラーが発生すると、Doorkeeper::TokensControllerの中でエラーが起きるので、ApplicationController

  • use_doorkeeperの中でdoorkeeperの処理に使うcontrollerを指定できる
  • Doorkeeper::TokensControllerはActionController::Metalを継承しているので、renderを実行するのに必要なmoduleをincludeする必要がある
  • /config/routes.rb

    MyAppServer::Application.routes.draw do
      use_doorkeeper do
        controllers tokens: 'tokens'
      end
    
      resources :books
      resources :users
    end
    

    /app/controllers/tokens_controller.rb

    class TokensController 
    	

    railsでsanitizeすると閉じタグを付け忘れた時にタグが続いてしまう

    sanitizeというメソッドを使うと、ホワイトリストに載ったHTMLタグ以外を削除して出力できる。例えば以下のようなコード(haml)を書くと、

    %p
      - dummy_text = '斜め'
      = raw(sanitize(dummy_text))
    
    斜め
    

    と出力される。

    通常はこれで問題ないが、タグが閉じられないままだと、続けて出力されてしまう。

    %p
      - dummy_texts = ['<i>斜め' '斜めったまま']
      - dummy_texts.each do |dummy_text|
        %p
          = raw(sanitize(dummy_text))
    

    ↓こんな感じ。

    斜め
    斜めったまま
    

    つまり、validではないHTMLをvalidにするにはどうすればいいかという問題。

    続きを読む railsでsanitizeすると閉じタグを付け忘れた時にタグが続いてしまう

    Mongoidのany_ofがorではなくandになる

    any_ofでorの結果を取得したいのに、結果はandになってしまう、という場合

    User.any_of(:created_at.gte => 1.week.ago, :name => /^j/)
    

    上記のコードは、1つのハッシュをany_ofとして渡している。any_ofはハッシュを複数渡すのが正解なので、以下のコードが正しい。

    User.any_of({:created_at.gte => 1.week.ago}, {:name => /^j/})
    

    よくミスするのでメモ。

    Rails + HAMLの環境で、URL Helperを使いながらjQuery Templateを使う

    JavaScirptで利用できるテンプレートエンジンに「jQuery Templates」がある。これにはjquery-tmpl-railsというgemも用意されていて、すぐに使い始めることができる。使い方のチュートリアルとしてはブログ記事”jQuery公式のテンプレートplugin 「jQuery Templates」-JavaScript Library Archive“が分かりやすい。

    railsのurl helperを使うと、routes.rbに書かれた内容に沿ってURLを自動で生成してくれる。例えば、routes.rbにresource :booksと書いていた場合、指定のIDのBookのページのURLを取得するにはbook_path(:id)と書けばよい。詳しくは以下参照。
    2.3 Paths and URLs – Ruby on Rails Guides: Rails Routing from the Outside In
    この時、:idに相当する部分は自動でURLエンコードされる。ここをjQuery Templatesで書き換えたい場合、ダラー( $ )と波括弧( { と } )がエスケープされてしまう。それを避ける方法。

    あまり綺麗な書き方ができなかったので、もっとベターな方法(例えばURLHelperの機能を使う時にURLエンコードを禁止するような方法)があったらどなたか教えてください。

    Rails: コントローラとモデルのリファクタリング

    railsのリファクタリングについて具体的な事例が掲載されていて分かりやすかったのでメモ。

    Railsで目指せ、情熱エンジニア(10):コントローラとモデルをリファクタリングする
    前回用意したRailsアプリのコントローラのテスト(スペック)をもとに、今回はコントローラとモデルのリファクタリングの実例を紹介します。
    http://www.atmarkit.co.jp/ait/articles/1305/28/news003.html

    Mongoidでcallback(before_save等)を呼ばずにupdateする

    before_save, after_saveといったコールバックを実行せずにフィールドの値を更新するには、setメソッドを利用する。after_saveの中で値を更新したい時に便利。
    以下は例。

    item = Item.first
    item.set(:description, "It's so nice!")
    

    簡単ですね。

    http://mongoid.org/en/mongoid/docs/persistence.html#atomic

    ActiveRecordでcallbackを呼ばずにupdateする

    ActiveRecord::Baseを継承したクラスの中で、before_save, after_saveなどを書くと、保存前や保存後に呼び出されるメソッドを指定できる。しかし、これらのコールバックの中で例えばsaveメソッドを実行してしまうと、stack level too deep (SystemStackError)というようなエラーが起きてしまう。

    参考にしたのは以下のページ:
    ruby on rails – Skipping callbacks and validation – Stack Overflow

    以下のドキュメントにリストアップされているメソッドは、こういったコールバックを呼び出さずにスキップして、updateをかけることができる。
    http://guides.rubyonrails.org/active_record_validations_callbacks.html#skipping-callbacks

    続きを読む ActiveRecordでcallbackを呼ばずにupdateする

    I18n.tで変数を使う/動的に翻訳を増やす

    I18n.tを使ってyamlから文字列を読み込んでいる時、文中に変数名を入れたいことがある。その場合は、yaml側では変数名を%{ }と囲んで、I18n.tの引数としてハッシュを渡せばよい。詳しくは、以下のドキュメントに記載されていた。

    http://guides.rubyonrails.org/i18n.html#interpolation

    上記URLからサンプルコードを引用:

    I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!'
    I18n.translate :thanks, :name => 'Jeremy'
    # => 'Thanks Jeremy!'