13F

備忘録

rails 2.0.2でhttp_authenticationがうまく動かない

2008-04-29 03:04:51 | Ruby
ふつうに
ruby script/plugin install http_authentication
ruby script/generate scaffold hoge
rake db:migrate
して、HogeControllerに
before_filter :authenticate
def authenticate
  authenticate_or_request_with_http_basic do |user, pass|
    true
  end
end
してるだけなんだけど、「protected method `render' called for #<HogeController...」みたいなNoMethodErrorが出て動かない。Google検索では同じような報告が数件あるものの原因はわかっていない。 関係する部分を簡略化すると下のような構造になっているようなんだけど、これだけ見ると逆になんで動く人がいるのか不思議だ。何か勘違いしているんだろうか?
module PluginModule
  extend self

  module ControllerMethods
    def authenticate
      PluginModule.authentication_request(self)
    end
  end

  # このメソッドも PluginModule も HogeController とは何の関係もない
  # ので、protected メソッドが呼べるとは思えない…
  def authentication_request(controller)
    controller.render
  end
end

class HogeController < ApplicationController
  def action
    authenticate
  end

protected
  def render
    puts "ok!"
  end
end

# プラグインの init.rb でやってること
ApplicationController.send :include, PluginModule::ControllerMethods

# ブラウザからなんか呼び出してみたときに行われること?
# protected method (render) へのアクセス違反が発生
HogeController.new.action
HogeControllerに public :render とか書いちゃえばもちろん動くんだけど問題ないんだろうか?

(追記)解決した。1.2.6 だと動くので、1.2.6 と 2.0.2 の差分を眺めていたら actionpack/lib/action_controller.rb のところでようやく気がついた。2.0 からはHTTP認証は組み込みになっていてプラグインは要らず、入れると逆におかしくなるってことのようだ。ちゃんと変更点は把握しないと。。

上の構造についても、controller.render のように直接呼び出すのではなく controller.send :render に変わっていてようやく納得・安心できた(個人的に、調べたときに何で動くのかわからないと怖くて使えない……)。ただ、1.2.6 でなんでうまくいくのかは謎のまま。