ActionView :: Template :: Error(错误的参数数量(1表示2)):

时间:2017-08-21 14:31:17

标签: ruby-on-rails ruby

我正在使用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>

2 个答案:

答案 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 2.0 +)

关键字参数在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 1.9)

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)