我的问题是在测试环境中调用旧的别名方法。可能只有工厂女孩
应用程序/模型/ 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
供应商/插件/../ 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
规格/模型/ user_spec.rb
describe User do
it 'test' do
@user = Factory(:user)
@user.should be_valid
end
end
规格/工厂/ 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
当我使用调试器gem调试它时,我发现方法old_password_required?
指向password_required?
中的新方法user.rb
而不是vendor/plugins/../by_password.rb
使用alias, alias_method or alias_method_chain
有什么想法吗?
答案 0 :(得分:1)
我的观点是:在Ruby中使用alias
通常是痛苦的屁股。那么如何将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