0

状況は次のとおりです。

User モデルと、認証用の 2 つのモジュール (Oauth と Openid) があります。どちらも をオーバーライドActiveRecord#saveし、実装ロジックをかなり共有しています。

ユーザーがいつ Oauth と Openid を介してログインしようとしているかがわかりますが、どちらもオーバーライドされているため、モジュールの実装の 1 つを条件付きで呼び出すことができるようにsave「最終的に」オーバーライドするにはどうすればよいでしょうか?save

これが私が説明しているものの基本構造です:

module UsesOauth

  def self.included(base)
    base.class_eval do
      def save
        puts "Saving with Oauth!"
      end

      def save_with_oauth
        save
      end
    end
  end

end

module UsesOpenid

  def self.included(base)
    base.class_eval do
      def save
        puts "Saving with OpenID!"
      end

      def save_with_openid
        save
      end
    end
  end

end

module Sequencer

  def save
    if using_oauth?
      save_with_oauth
    elsif using_openid?
      save_with_openid
    else
      super
    end
  end

end

class User < ActiveRecord::Base
  include UsesOauth
  include UsesOpenid
  include Sequencer
end

私はalias_methodso のように使用することを考えていましたが、1 つまたは 2 つの同様のモジュールがある可能性があるため、複雑になりすぎました。また、これらのsave_with_oauth方法(上記)を使用してみましたが、ほとんど機能します。欠けている唯一のことは、ActiveRecord::Base#save(スーパーメソッド) も呼び出す必要があることです。したがって、次のようになります。

def save_with_oauth
  # do this and that
  super.save
  # the rest
end

しかし、Ruby でそれを行うことは許可されていません。

これに対する賢い解決策のアイデアはありますか?

それは何alias_method_chainをするでしょうか?人々がそれは悪い考えだと言っているようだったので、私はそれを避けてきました.

(私が行くように物事を見つける):

4

1 に答える 1

2

はい、この状況ではエイリアスメソッドチェーンが役立ちます。

ただし、デリゲート パターンの使用を検討してください。元の save メソッドは、特別なデリゲート オブジェクト (nil の場合もある) でコールバックをトリガーし、ユーザーを保存するときに実行する必要があることは何でも実行します。

また、Observer と呼ばれるアクティブ レコードによって直接サポートされている同様のパターンもあります。それについて何かを読んでみてください。

このチェーン方法が間違っていると言っているわけではありませんが、目的を達成するためのよりクリーンな方法があります。

于 2010-05-10T08:45:38.970 に答える