我正在使用Rails应用程序,该应用程序主要基于Michael Hartl的Rails教程。我在Logentries中遇到了一个我无法追踪的错误。
ActionView::Template::Error (wrong number of arguments (1 for 2)):
31: <div class="inner">
32: <h1 id="fadeThis" style="display: none;">The Lake County Bar Association</h1>
33:
heroku router - - at=info method=GET path="/" host=www.example.org request_id="REMOVED" fwd="xx.xx.xx.xx" dyno=web.1 connect=1ms service=10ms status=500 bytes=1669 protocol=http
34: <% if logged_in? %>
35: <br>
36: <h2 class="margin-top-0 wow fadeIn" id="welcomeText"> Welcome back, <%= current_user.first_name %>! </h2>
37: <% else %>
app/models/user.rb:46:in `authenticated?'
app/helpers/sessions_helper.rb:11:in `current_user'
app/helpers/sessions_helper.rb:21:in `logged_in?'
app/views/static_pages/home.html.erb:34:in `_app_views_static_pages_home_html_erb__118074299580396133_69921140988760'
以下是经过验证的? user.rb中的方法:
def authenticated?(remember_token)
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
还有current_user和logged_in? sessions_helper.rb中的方法:
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
def logged_in?
!current_user.nil?
end
home.html.erb的相关部分:
<% if logged_in? %>
<br>
<h2 class="margin-top-0 wow fadeIn" id="welcomeText"> Welcome back, <%= current_user.first_name %>! </h2>
<% else %>
<h3> <span class="element"> <br></span></h3>
<hr>
<br>
答案 0 :(得分:1)
Ruby并不真正支持方法重载。从doc
开始您希望使用相同的方法创建两个不同版本的方法 name:两种方法,它们采用的参数不同。但是,一个 Ruby类只能有一个具有给定名称的方法(如果你定义了一个 具有相同名称的方法两次,后一种方法定义优先
因此,在您的情况下,只会调用authenticated?(attribute, token)
答案 1 :(得分:1)
如上所述, Ruby不支持基于参数的方法重载。为了能够做你想做的事,你可以使用参数,关键字参数或选项哈希。
我首选的是关键字参数,因为我已经在Python中看到了很多,并且非常清楚它是多么清晰。您的偏好或项目偏好可能不同。
def authenticated?(*args)
case args.count
when 1
remember_token = args[0]
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
when 2
attribute, token = args
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
end
调用方法:
authenticated?(false)
authenticated?('whatever', 'cool')
您还可以检查参数的类型或使用参数排序(例如authenticated?(nil, nil, true)
,其中前两个参数是属性和标记,第三个参数是remember_token)。
关键字参数在Ruby中使用不足,但自Ruby 2.0以来就已经可用。
def authenticated?(remember_token: nil, attribute: nil, token: nil)
if remember_token
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
elsif attribute && token
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
end
调用方法:
authenticated?(attribute: 'whatever', token: 'cool')
authenticated?(remember_token: false)
Ruby中非常常见的模式/习惯使用选项哈希:
def authenticated?(options = {})
if options['remember_token']
return false if options['remember_token'].nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
elsif options['attribute'] && options['token']
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
end
调用方法:
authenticated?(:attribute => 'whatever', :token => 'cool')
authenticated?(:remember_token => false)