views:

628

answers:

2

I followed the official Authlogic tutorial but something came up.

I successfully created a user, but when I try to show his profile page, I get the following error:

undefined method `email' for #<UserSession: {:unauthorized_record=>"<protected>"}>

Here's the relevant code:

# user.rb
class User < ActiveRecord::Base  
  acts_as_authentic do |c|
    c.crypto_provider = Authlogic::CryptoProviders::BCrypt
    c.require_password_confirmation(false)
  end  
  attr_accessible :username, :email, :password  
end

# users_controller.rb    
def show
  @user = @current_user
end

# application_controller.rb
private
  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end

  def current_user
    return @current_user if defined?(@current_user)
    @current_user = current_user_session and current_user_session.user
  end

I think that's the entire chain. And here's the view:

# views/users/show.html.erb
<%=h @user.username%>
email: <%=h @user.email %>
<%= link_to "Edit", edit_account_path %>

When I remove the "email" line, I get a page with only the "Edit" link. The username does not appear. However, when I add <%= debug @user %> to see what's going on, it correctly prints the values for email and username as stored in the database. I have no idea why it does not print @user.username, and why it throws an error when I try to print @user.email.

It should be noted that the show.html.erb layout of the tutorial uses @user.login, and it works. I just changed "login" to "username".

Furthermore, when I click "Edit", I get the same original error:

undefined method `email' for #<UserSession: {:unauthorized_record=>"<protected>"}>

Here's the edit layout and the form partial used:

# views/users/edit.html.erb
<h1>Edit My Account</h1>

<% form_for @user, :url => account_path do |f| %>
  <%= f.error_messages %>
  <%= render :partial => "form", :object => f %>
  <%= f.submit "Update" %>
<% end %>
<br />
<%= link_to "My Profile", account_path %>

#views/users/_form.erb
<%= form.label :username %><br />
<%= form.text_field :username %><br />
<br />
<%= form.label :email %><br />
<%= form.text_field :email %><br />
<br />
<%= form.label :password, form.object.new_record? ? nil : "Change password" %><br />
<%= form.password_field :password %><br />
<br />

Again, all taken verbatim from the tutorial, that just works.

I'm running Rails 2.3.2 and the latest Authlogic (just installed today, whatever version that is), and as far as my tired and frustrated brain can tell, I do have all required fields in the database, and they are spelled correctly.

What's going on?

A: 

I think you want to have the following code instead:

# users_controller.rb    
def show
  @user = current_user
end

Notice that current_user is actually a method rather than an instance variable @current_user.

adimitri
The method `current_user` returns `@current_user`. But I tried it anyway and nothing changed. But thanks.
Baby Diego
A: 

Well, this is embarrassing…

It turns out the problem was my predilection for natural language. Here's the current_user method as laid out in the tutorial:

def current_user
  return @current_user if defined?(@current_user)
  @current_user = current_user_session && current_user_session.user
end

However, when applying it to my case, I swapped && for and, and as a result current_user_session.user was not being taken into account. Which is why it kept saying UserSession this and that. I thought that was weird, but couldn't see where it was coming from. Now I do.

Baby Diego