Still a little confused in terms of sequence of operation:
1) A request for URL is made (e.g. www.mysite.com/login). The URL is
matched against a route to find the corresponding controller. So I have
this:
map.signup "signup", :controller => "users", :action => "signup"
Hence, the signup URL string is mapped against the UsersController. Now
Rails knows that the file containing the controller can be found as
apps/controllers/users_controller.rb. The signup portion of query string
is matched against the signup action of the UsersController, which is
represented by a signup method in the controller.
2) Hence, at this point that method is invoked:
def signup
@user = User.new(params[:user])
if request.post?
if @user.save
session[:user] = User.authenticate(@user.login, @user.password)
flash[:message] = "Signup successful"
redirect_to :action => "root"
else
flash[:warning] = "Signup unsuccessful"
end
end
end
We instantiate new User object, passing it arguments from the parameter
hash passed via query sring. When page first loads, these parameters
will all be equal to nil since no assignment has been made to the
properties of the User object (because no user input occurred yet):
<User id: nil, login: nil, hashed_password: nil, email: nil, salt: nil,
created_at: nil>
Nevertheless these properties are "own members" (instance methods) of
the Object instance, courtesy of the hash iteration described above
where setters and getter methods are dynamically created at run time:
def login=(p)
@p = p #if no parameter passed, nil returned implicitly in Ruby?
end
def login
@p
end
@user.login #nil
User now fills out form and submits it:
<% content_for :signup do %>
<% form_for @user, :url => { :action => "signup" } do |f| %>
<%= error_messages_for 'user' %><br/>
<%= f.label(:user_login, "Username")%>
<%= f.text_field(:login) %><br/>
<%= f.label(:user_password, "User Password")%>
<%= f.password_field(:password) %><br/>
<%= f.label(:user_password_confirmation, "Password Confirmation")%>
<%= f.password_field(:password_confirmation) %><br/>
<%= f.label(:user_email, "User Email")%>
<%= f.text_field(:email)%>
<%= f.submit("Sign Up") %>
<% end %>
<% end %>
Here, the signup method is called again but this time it's not a GET
request. It's a POST request. We also now have values for our key hash.
And interestingly there is a method here called password that gets as
parameter of predefined password_field method. There is no password
method in our users table. Ruby must resolve it, so it checks the
instance methods of our user instance and indeed it finds it:
attr_accessor :password, :password_confirmation
def password=(pass)
@password=pass
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)
end
Basically this just populates our salt and hashed_password properties to
ensure protection of our user. Ultimately, we now have values for our
properties of our instance. Since we are dealing with post request, we
save the user calling predefined save method of ApplicationController??
(who knows).
if request.post?
if @user.save
session[:user] = User.authenticate(@user.login, @user.password)
And store the user as part of current session.
Is this a correct analysis in terms of sequence of events?
A real gray area for me is when the instance variable @user stores the
correct value in signup.html.erb with an appropriate reference to
current instance. Does this it become available as soon as the method is
called in controller? Or is there some more magic going on that makes it
available?
Thanks for response.
--
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.