Undefined локальная переменная или метод 'current_user'
В настоящее время я просматриваю учебник RoR (http://railstutorial.org/chapters/sign-in-sign-out#sec:signin_success - это соответствующий раздел), который кажется довольно хорошим, при попытке просмотреть образец сайта, вы сталкиваетесь со следующей проблемой.
Extracted source (around line #10):
7: <li><%= link_to "Home", root_path %></li>
8: <li><%= link_to "About", about_path %></li>
9:
10: <% if signed_in? %>
11: <li><%= link_to "Profile", current_user %></li>
12: <li><%= link_to "Sign out", signout_path, :method => delete %></li>
13: <% else %>
Как вы можете видеть, проблема связана с моим методом "signed_in"? который должен проверить, был ли пользователь зарегистрирован или нет, проверяя, установлена ли переменная current_user (я включил остальную часть кода из помощника, чтобы дать контекст, извинения):
module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
current_user = user
end
def sign_out
cookies.delete[:remember_token]
current_user = nil
end
def current_user= (user)
@current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
Из моего понимания,.nil? это метод, который проверяет, был ли объект определен, и поэтому объект undefined не должен генерировать ошибку, а скорее возвращает false? Я искал учебник для всех случаев current_user (прежде чем проверять, есть ли у кого-либо еще эта проблема с небольшим успехом), и мой код кажется правильным, поэтому я немного запутался, и если кто-то может помочь мне понять, как переменные Ruby должен быть доступен, и почему мой код не работает, я был бы очень благодарен.
Edit:
Я не уверен, что это важно с областью действия, поскольку я только начинаю как Rails, так и Ruby, однако помощник SessionsHelper используется моим контроллером и представлениями пользователей (он входит в мой контроллер приложений)
Ответы
Ответ 1
Я столкнулся с этой проблемой и по той же причине. Вы упустили часть инструкций в "Листинг 9.16".
def current_user= (user)
@current_user ||= user_from_remember_token
end
Вы должны были изменить это на следующее.
def current_user
@current_user ||= user_from_remember_token
end
Вы также захотите изменить все экземпляры * self. * current_user на * @* current_user.
Как только вы это сделаете, ошибки (ошибки) будут разрешены.
Ответ 2
Убедитесь, что у вас есть следующий код в SessionHelper
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= user_from_remember_token
end
Ответ 3
Ноль? метод не собирается проверять, определена ли переменная или метод. Он исключительно проверяет, определен ли он как объект nil или нет. Ruby поднимает цепочку предков для SessionHelper и, наконец, определяет, что current_user не определен нигде (он в конечном итоге закончится в Kernel # method_missing), а затем выдает ошибку. Самый быстрый способ решить проблему:
#app/helpers/sessions_helper.rb
def current_user
@current_user ||= false
end
Ответ 4
Я спросил друга, и он исправил мои ошибки. Я думаю, что большая часть моей ошибки возникла из-за того, что не была полностью знакома с переменной областью действия в Ruby и забыла, что все является объектом, и поэтому метод current_user = (пользователь) переопределяет функцию присваивания.
Другим решением было изменить область действия current_user на инстантивную переменную (чтобы ее можно было правильно использовать) и изменить функцию curent_user = (пользователь) на простую функцию get_current_user, чтобы определить, существует ли текущий пользователь в cookie.
Окончательный измененный код выглядит следующим образом:
#app/helpers/sessions_helper.rb
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
@current_user = user
end
def sign_out
cookies.delete(:remember_token)
@current_user = nil
end
def get_current_user
@current_user ||= user_from_remember_token
end
def signed_in?
!get_current_user.nil?
end
#app/views/layouts/_header.erb
<% if signed_in? %>
<li><%= link_to "Profile", get_current_user %></li>
<li><%= link_to "Sign out", signout_path, :method => :delete %></li>
<% else %>
<li><%= link_to "Sign in", signin_path %></li>
<% end %>
Как вы видите, переменная в моем частичном части заголовка также была изменена, чтобы отразить метод, используемый в помощнике для получения пользователя.
Приступая к чтению некоторых основных рубиновых руководств, так что в следующий раз, когда я попаду себе в голову, у меня есть идея, с чего начать исправление:)