2015-06-03 3 views
1

Я нахожусь в разделе 8.4.3 - Forgetting Users руководства Rails.Rails Tutorial: использование переменных экземпляра

# app/helpers/session_helper.rb 
module SessionsHelper 
... 
    # Returns the user corresponding to the remember token cookie. 
    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 

    # Logs out the current user 
    def log_out 
    forget(current_user) 
    session.delete(:user_id) 
    @current_user = nil 
    end 
... 
end 

В методе current_user мы назначить пользователю переменной в @current_user экземпляра. Я не понимаю, почему мы не используем ту же переменную экземпляра в методе log_out (в этом методе current_user не добавляется с символом @). Откуда возникает current_user, так как он не передан в качестве аргумента этому методу?

+2

current_user - это вспомогательный метод https://github.com/plataformatec/devise#controller-filters-and-helpers –

+2

'forget (current_user)' он вызывает хелпер 'current_user'. Рубиновые методы по умолчанию возвращают последнюю выполненную строку. Таким образом, помощник 'current_user' возвращает объект @ @ current_user', если пользователь logged_id. –

+1

Важно также отметить, что '@ current_user' не задан, пока вы не вызовете метод' current_user'. Поэтому в рамках метода 'log_out' вы должны предположить, что' @ current_user' не существует, пока вы не запустите метод, который его создает, то есть 'current_user'. – Clark

ответ

1

Ruby не делает разницы между вызовом метода и локальной переменной. Вот почему current_user может выглядеть как и то, и другое. В вашем случае это определенный метод.

Вы можете использовать как @current_user, так и current_user, так как возвращаемое значение этого метода должно быть равно @current_user.

1

current_user - это метод, определенный в фрагменте, опубликованном на странице.

@current_user является переменной экземпляра, установленного current_user

Итак, когда вы смотрите на код:

# Defines a method called log_out 
def log_out 
    # Calls the 'forget' method on the result of the 'current_user' method, 
    # which sets @current_user 
    forget(current_user) 
    # Deletes the session variable named 'user_id' 
    session.delete(:user_id) 
    # Resets @current_user to nil, because there should no longer be one 
    @current_user = nil 
end 

Если бы я хотел, чтобы посмотреть на это по-другому, я мог бы сказать:

def log_out 
    # Sets @current_user 
    current_user 
    # Calls the forget method on the variable @current_user 
    forget(@current_user) 
    session.delete(:user_id) 
    @current_user = nil 
end 

Но я не мог изменить последнюю строку на current_user = nil вместо @current_user = nil, потому что тогда я присваиваю значение nil имя метода вместо переменной экземпляра.

Часть вызова метода и переменные выглядят настолько похожими в Ruby, что все обрабатывается как объект, поэтому методы по существу просто переменная, значение которой является блоком кода (есть технические отличия от того, что мы назовите «блок» и метод, но концептуально это достойная аналогия). Когда мы определяем метод, мы сохраняем его в том, что является более или менее переменной. Таким образом, если мы подумаем о методе «current_user», мы можем вместо этого думать об этом как переменную «current_user», значение которой равно forget(current_user); session.delete(:user_id); @current_user=nil.

Это, конечно, упрощение, но стоит иметь в виду, когда вы продвигаетесь вперед с обучением.