Filippos wrote in post #1013927: > Studying the RoR 3 Tutorial book by Michael Hartl > and on page 345 there's the code inside the SessionsHelper: > > _________________________________________________________ > module SessionsHelper > > def sign_in(user) > cookies.permanent.signed[:remember_token] = [user.id, user.sault] > self.current_user = user > end > > end > __________________________________________________________ > > What is the purpose of "self" inside the session helper? > I know that inside a model it refers to the class object. > For example > > Class User < ActiveRecord::Base > self.salt > > it refers to User.salt > > But when it is inside a helper, does it refer to the helper itself?
Remember that no code inside a method actually executes until the method is called. When the signin method is actually called by some object, for instance: some_object.sign_in(userA) ...then inside the sign_in() method, self is equal to the object that called the sign_in method, which in this case is some_object. However, the book never talks about what object is calling the various methods. Instead, you have a controller like this: class SessionsController < ApplicationController def new end def create end def destroy end end and the book talks about some url getting mapped to the new action, which then causes rails to execute the file new.html.erb (and then rails sends the resulting new.html file back to the browser). But if you know any ruby, then you can infer that rails has to create a SessionsController object, like this: sess_controller = SessionsController.new in order to be able to call the new, create, and destroy methods, e.g. sess_controller.new That part of the book confused me, too, because instead of this: def sign_in ... self.current_user = user end you could also write: def sign_in @current_user = user end but you definitely cannot write: def sign_in .. current_user = user end That creates a 'local variable' called current_user which will be destroyed when the sign_in method finishes executing. '@' variables persist as long as the sess_controller object still exists. The way this code works: def sign_in ... self.current_user = user end is the self is the object calling the sign_in method. What object is calling the sign_in method? That is a bit convoluted. The sign_in method is in a module called SessionsHelpers, and you have this code in a file: class ApplicationController < ActionController::Base protect_from_forgery include SessionsHelper end That means all the methods in SessionsHelper become methods in the ApplicationController class. But you also have this file: class SessionsController < ApplicationController def new end def create end def destroy end end ..so through inheritance all the ApplicationController methods become methods of SessionsController--including the SessionsHelper methods. In the end, that means a SessionsController object, e.g. sess_controller = SessionsController.new is the object that is going to be calling the sign_in method, and so inside the sign_in method self is going to be equal to sess_controller. Of course, rails calls sign_up behind the scenes, so what object is calling sign_up isn't obvious, and therefore determining what self is inside the sign_up method isn't obvious. Now the question is why use self in the sign_in method here: def sign_in ... self.current_user = user end when you can avoid all that confusing stuff and just write: def sign_in @current_user = user end The short answer: it's good practice to always use an accessor method to access an instance variable--rather than assign directly to an instance variable. The reason is that if, for instance, you want to apply some kind of transformation to a value before assigning it to an instance variable, you can do that in the current_user=() method rather than hunting through your code and looking for every @current_user = ... line and making the change to each of those lines. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

