"}> I am trying to create a system "just click on your login name" using auth_logic. My user ...">

# <UserSession: {: unauthorized_record => "<protected>"}>

I am trying to create a system "just click on your login name" using auth_logic. My user model has an email address and name. To log in, I simply do:

UserSession.create(@user, true) 

Unfortunately, this does not lead to a session. Using a debugger, I found this message:

 #<UserSession: {:unauthorized_record=>"<protected>"}> 

My user model has only one line:

 acts_as_authentic 

There is something in the user session line that I found somewhere. I'm not sure what it does, and I tried with and without:

 class UserSession < Authlogic::Session::Base def to_key new_record? ? nil : [ self.send(self.class.primary_key) ] end end 

Database (I'm also not sure if this user_sessions table is needed):

 create_table "sessions", :force => true do |t| t.string "session_id", :null => false t.text "data" t.datetime "created_at" t.datetime "updated_at" end add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" create_table "user_sessions", :force => true do |t| t.datetime "created_at" t.datetime "updated_at" end create_table "users", :force => true do |t| t.datetime "created_at" t.datetime "updated_at" t.string "persistence_token" t.string "email" t.string "name" end 

I am using Rails 3.0.9, and my Gemfile says (I tried both normal and Ghitub authlogic gem):

 gem 'rails', '3.0.9' gem 'sqlite3' gem "authlogic" #, :git => 'git://github.com/odorcicd/authlogic.git', :branch => 'rails3' 

Here is the rest of the source code.

I had this problem a few days ago on a similar project, and at some point it "just left." I just don't remember how.

Any ideas? It drives me crazy...

+6
source share
2 answers

Possible solution ... there seem to be two versions of these examples of helper methods floating around. There is one that we used:

 @current_user = current_user_session && current_user_session.user 

and then a newer version , which is in some new tutorials and examples:

 @current_user = current_user_session && current_user_session.record 

Apparently, when .user (or whatever the login field) is called in the session object, it returns unauthorized_record, while .record.user returns the corresponding data.

+2
source

I recently ran into this problem and was also embarrassed. I figured out my specific problem with the code, so this is another potential solution.

TL; DR

I did not understand that #<UserSession: {:unauthorized_record=>"<protected>"}> user session is still valid, just not associated with it, which we created ourselves. You can confirm this by calling user on it, and you should get the user instance that you passed to UserSession.create .

Cause

The real problem is twice. The current_user method was built with the assumption that the current user will not change throughout the life of the request, and I called current_user before creating one to make sure I don't have one yet. It can be simplified as follows:

 def current_user return @current_user if defined?(@current_user) @current_user = some_method_that_finds_a_proper_user end 

The key here is that my user search method can return nil . When this happens, it will define @current_user as nil and thus the cached value will always be returned on subsequent calls.

Decision

Here, where it gets a little trickier as it really depends on what your code needs.

  • If you do not need current_user after signing up the user model using UserSession.create , you do not need to do anything other than wait for a render or redirect. On the next request, your current_user will be set correctly.

  • If you do not need to check for an already registered user, delete all current_user calls before UserSession.create if you can, and your first current_user call will work as expected.

  • Ensure that the method chain that creates current_user does not use caching, does not cache nil s, or change the protection for these cached values ​​to determine if the value is true and not if an instance variable is defined. The guard can be changed to:

     return @current_user if !@current _user.nil? # or @current_user.present? in Rails 

    Or you can use the Ruby ||= operator and implicit return. Instead of my simplified example, it might be:

     def current_user @current_user ||= some_method_that_finds_a_proper_user end 

    or if it's not so simple

     def current_user @current_user ||= begin some_code doing_many things_here end end 
  • Or your problem may be that you are having trouble writing a test for this behavior. In this case, I would rather just animate the code, for example

     expect(UserSession).to receive(:create).with(user) 
+1
source

Source: https://habr.com/ru/post/892423/


All Articles