неопределенная локальная переменная или метод 'current_user' - PullRequest
12 голосов
/ 13 ноября 2010

В настоящее время я прохожу учебное пособие по 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 %>

Как вы можете видеть, проблема связана с моим методом "signature_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? метод, который проверяет, был ли определен объект и, следовательно, неопределенный объект не должен генерировать ошибку, а скорее возвращать false? Я искал учебник для всех случаев current_user (перед проверкой, чтобы увидеть, если кто-то еще имел эту проблему с небольшим успехом), и мой код кажется правильным, поэтому я немного запутался, и если кто-нибудь сможет помочь мне понять, как переменные Ruby должен быть доступен, и почему мой код не работает, я был бы очень признателен.

Edit:

Я не уверен, что это важно с областью видимости, поскольку я только начинаю и Rails, и Ruby, однако вспомогательный SessionsHelper используется моим контроллером Users и представлениями (он включен в мой контроллер Applications)

Ответы [ 4 ]

7 голосов
/ 07 октября 2011

Я столкнулся с той же проблемой, и это было по той же причине.Вы пропустили часть инструкций в «Листинге 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 to *@*current_user.

Как только вы сделаете это, ошибки будут устранены.

4 голосов
/ 16 февраля 2011

Убедитесь, что у вас есть следующий код в SessionHelper

def current_user=(user)
    @current_user = user
end

def current_user
    @current_user ||= user_from_remember_token
end
2 голосов
/ 14 ноября 2010

Я спросил друга, и он исправил мои ошибки. Я думаю, что большая часть моей ошибки произошла из-за того, что я не был полностью знаком с областью переменных в Ruby и забыл, что все является объектом, и поэтому метод current_user = (user) переопределял функцию присваивания.

Решение моего друга состояло в том, чтобы изменить область действия current_user на экземплярную переменную (чтобы ее можно было правильно использовать) и изменить функцию curent_user = (user) на простую функцию get_current_user для определения, существует ли текущий пользователь печенье.

Последний измененный код выглядит следующим образом:

#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 %>

Как видите, переменная в моем заголовке частично также была изменена, чтобы отразить метод, используемый в помощнике для получения пользователя.

Собираюсь начать читать некоторые основные руководства по Ruby, так что в следующий раз, когда я зайду над головой, у меня будет представление о том, с чего начать это исправлять:)

2 голосов
/ 13 ноября 2010

Ноль? Метод не собирается проверять, определена ли переменная или метод. Он исключительно проверяет, определен ли он как нулевой объект или нет. Руби проходит по цепочке предков для SessionsHelper и, наконец, определяет, что current_user нигде не определен (в конечном итоге он заканчивается в Kernel # method_missing), а затем выдает ошибку. Самый быстрый способ решить эту проблему:

#app/helpers/sessions_helper.rb
def current_user
  @current_user ||= false
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...