A.J*_*A.J 1 ruby sql arrays activerecord ruby-on-rails
我试图限制每个失败的登录尝试ip。
我有以下内容:
def validate(email, context)
attempt = insert_into_attempts(email, context)
return nil unless allow_login_by_ip(context.ip_address)
flag_successful_attempt(attempt, context.ip_address)
load_data
end
def allow_login_by_ip(ip_address)
limit = LoginLimits.new(ip_address).limit
last_5_attempts = AuthenticationAttempt.select("id","successful").where(ip: ip_address).last(5)
last_5_attempts.include?("true")
end
def insert_into_attempts(email, context)
attempt = AuthenticationAttempt.new(
:email => email,
:ip => context.ip_address)
attempt.save
end
def flag_successful_attempt(attempt, ip_address)
AuthenticationAttempt.where(ip: ip_address).last.update(successful: '1')
end
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是它总是返回fasle。我一定是搜索array错误,但我不知道为什么。last_5_attempts是:
#<AuthenticationAttempt id: 1, successful: false>,
#<AuthenticationAttempt id: 2, successful: false>,
#<AuthenticationAttempt id: 3, successful: true>,
#<AuthenticationAttempt id: 4, successful: false>,
#<AuthenticationAttempt id: 5, successful: false>]
Run Code Online (Sandbox Code Playgroud)
如果你的意思是true,那么你的意思是:
last_5_attempts.include?(true)
Run Code Online (Sandbox Code Playgroud)
因为:
true == "true"
# => false
Run Code Online (Sandbox Code Playgroud)
但这还不够,因为您询问值数组是否有任何实际上只是, ( )[id, successful]的条目,所以您想要:true[1,true] != true
last_5_attempts.any? |id, successful|
successful
end
Run Code Online (Sandbox Code Playgroud)
您还可以id从列获取中省略,因为您不使用它,而是:
AuthenticationAttempt.where(ip: ip_address).pluck(:successful).last(5).any?
Run Code Online (Sandbox Code Playgroud)
如果pluck使用单个参数,则返回一个“平面”数组,而不是数组的数组。
要检查最近 5 次中是否至少有一次成功登录或没有登录历史记录:
attempts = AuthenticationAttempt.where(ip: ip_address)
!attempts.any? or attempts.pluck(:successful).last(5).any?
Run Code Online (Sandbox Code Playgroud)