开发者

self.method calls within methods

I am a ruby on rails newbie. below is a part of a sign in code to remember the session once a user signed in. I got this code from a ruby on rails tutorial and trying to learn. here within sign_in method we define

self.current_user=user 

and right after that we have two different current_user methods. If I remove the first one it gives an error message.

Why do we need to define method such as (def current_user= ) if we use an expression like self.curr开发者_JS百科ent_user=user?

why is it necessary to do this? and I dont understand why we again define another current_user method. Cant we just put this in to the first one? Plese see below. and many thanks.

def sign_in(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  self.current_user = user
end
def current_user=(user)
  @current_user=user
end
def current_user
  @current_user ||= user_from_remember_token
end

FULL CODE:

def sign_in(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  self.current_user = user
end

def current_user=(user)
  @current_user = user
end
def current_user
  @current_user ||= user_from_remember_token
end

private

def user_from_remember_token
  User.authenticate_with_salt(*remember_token)
end

def remember_token
  cookies.signed[:remember_token] || [nil, nil]
end


The methods that are defined for current_user are the setter/getter methods.

#setter
def current_user=(user)
  @current_user=user
end

#getter
def current_user
  @current_user ||= user_from_remember_token
end

Note that for the setter method the name ends with an = sign.

In sign_in method when you do self.curcrent_user = user you actually call the setter, you don't access the instance variable current_user. Accessing it would be @current_user=user. This is why you receive an error if you delete it.

Usually you need setter/getters in order to be able to set and get stuff from outside of the class. For example if you would want to retrieve later the current user you would call current_user on an instance of your class.

Although I must admit that I don't see to much sense in having a public setter in this case. Usually you would want sign_in and sign_off methods and not an explicitly current_user=.


The two current_user methods are actually two different methods, one for setting the current_user variable and the other for getting it again, which is actually using a pattern called memoization (more on that below).

the current_user=(user) method sets the an instance variable (the are various levels of variable scope in ruby variables starting with @ are scoped to an instance - see this page for more information). def current_user then returns the contents of the same variable*.

*Unless the @current_user variable has not been set. This is the purpose of the @current_user ||= user_from_remember_token line. What this is effectively saying is 'return the contents of the @current_user variable unless it's not been set, in which case return the result of running the method user_from_remember_token and also set the @current_user variable to the same'. This is a technique called memoization (read here why this is a good thing)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜