2

Rails アプリで Sorcery ライブラリを使用しています。そのモジュールの 1 つは外部認証用であり、そのモジュールにメソッドを追加する必要があります。

既存のコードはこちらです。このパッチadd_provider_to_userからメソッドを追加したいと思います。

そのため、ディレクトリにファイルを追加し、lib/modulesレールに自動ロードするように指示しました。ファイルが呼び出されsorcery_extension.rb、次のようになります。

module Sorcery
  module Controller
    module Submodules
      module External
        module InstanceMethods
          protected

          # If user is logged, he can add all available providers into his account
          def add_provider_to_user(provider)
            provider_name = provider.to_sym
            provider = Config.send(provider_name)
            user_hash = provider.get_user_hash
            config = user_class.sorcery_config

            user = current_user.send(config.authentications_class.to_s.downcase.pluralize).build(config.provider_uid_attribute_name => user_hash[:uid], config.provider_attribute_name => provider)
            user.save(:validate => false)

            return user
          end
        end
      end
    end
  end
end

これはうまくいきませんでした。コントローラーにundefined method error入ります (他のソーサリー メソッドの呼び出しは正常に機能します)。

したがって、Ruby に関する私の基本的な理解は、いつでもオブジェクトまたはモジュールにメソッドを追加できるということです...モジュールのネストをファイルに正しくコピーしたと思います。モジュールファイルに別の名前を付ける必要がありますか? この種のことを行う方法がよくわからないので、どんな助けでも大歓迎です。ありがとう!

4

2 に答える 2

1

あなたのファイルは決してrequiredではありません。コンソールに次のように入力して、これを再確認できます。

Sorcery::Controller::Submodules::External::InstanceMethods.method_defined?(:add_provider_to_user)
  # => will return false, you want true

その理由は、定数が不明な場合にのみ自動ロードが発生するためです。その場合、Rails は別の自動ロードされたパスから定数を自動ロードしようとします。

ファイルを明示的に (たとえば、イニシャライザのファイルから) 要求する必要があり、期待どおりに機能します。

于 2012-04-30T02:12:25.400 に答える
1

require に関する Rails の規則では、すべてのモジュールについて、同じ名前のディレクトリを検索します。

あなたの例では

module Sorcery
  module Controller
    module Submodules
      module External
       module InstanceMethods

モジュールを lib ディレクトリに配置する場合。「autorequire」になると、Railsはこのパスでそれを期待します

lib/sorcery/controller/submodules/external/instance_methods.rb

これが、モジュールのネストを浅くすることが一般的に良い慣習である理由です。~ 2 レベルの深さ。

于 2012-04-30T04:11:28.123 に答える