Ruby, Rails и aliasing - слишком большая проблема в стеке - PullRequest
0 голосов
/ 24 июля 2011

Моя проблема с вызовом старого метода с псевдонимом в тестовой среде.Вероятно, только с приложением Factory Girl

app / models / user.rb

class User < ActiveRecord::Base
  ...
  include Authentication
  include Authentication::ByPassword
  ...

  attr_accessor :skip_password_validations

  alias old_password_required? password_required?
  # alias_method :old_password_required?, :password_required?
  def password_required?
    return false if !!skip_password_validations
    old_password_required?
  end

  # def password_required_with_skip_validations?
  #   return false if !!skip_password_validations
  #   password_required_without_skip_validations?
  # end
  # alias_method_chain :password_required?, :skip_validations  
end

vendor / plugins /../ by_password.rb

module Authentication
  module ByPassword
    # Stuff directives into including module
    def self.included(recipient)
      recipient.class_eval do
        include ModelInstanceMethods
        attr_accessor :password
        validates_presence_of :password, :if => :password_required?
      end
    end # #included directives

    module ModelInstanceMethods 
      def password_required?
        crypted_password.blank? || !password.blank?
      end
    end # instance methods
  end
end

spec / models /user_spec.rb

describe User do
    it 'test' do
      @user = Factory(:user)
      @user.should be_valid
    end
 end

spec / factories / user_factories.rb

FactoryGirl.define do
  factory :user do |u|
    u.sequence(:email) { |n| "login#{n}@example.com" }
    u.password 'qwertz123'
    u.password_confirmation 'qwertz123'
  end
end

Результат равен

1) User test
     Failure/Error: Unable to find matching line from backtrace
     SystemStackError:
       stack level too deep
     # /Users/schovi/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.0.rc4/lib/active_record/connection_adapters/abstract/database_statements.rb:197

Когда я отлаживал его с помощью гема отладчика, я обнаружил, чтометод old_password_required? указывает на новый метод password_required? в user.rb, а не в vendor/plugins/../by_password.rb

Получить тот же результат с alias, alias_method or alias_method_chain

Есть идеи?

1 Ответ

1 голос
/ 24 июля 2011

Мое мнение таково: использование alias в Ruby часто вызывает боль в заднице. Так как насчет перемещения вашего password_required? в его собственный модуль и вызова super внутри него для вызова password_required? из Authentication::ByPassword::ModelInstanceMethods, например, так:

class User < ActiveRecord::Base
  module PasswordRequired
    def password_required?
      return false if !!skip_password_validations
      super # Is going to call Authentication's password_required?
    end
  end

  include Authentication
  include Authentication::ByPassword
  include PasswordRequired

  ...

end
...