views:

41

answers:

1

Hi!

I'm having a weird issue that I can't track down... For context, I have resources of Users, Registries, and Giftlines. Each User has many Registries. Each Registry has many Giftlines. It's a belongs to association for them in a reverse manner.

What is basically happening, is that when I am creating a giftline, the giftline itself is created properly, and linked to its associated Registry properly, but then in the process of being redirected back to the Registry show page, the session[:user_id] variable is cleared and I'm logged out.

As far as I can tell, where it goes wrong is here in the registries_controller:

  def show
    @registry = Registry.find(params[:id])
    @user = User.find(@registry.user_id)
    if (params[:user_id] && (@user.login != params[:user_id]) )
      flash[:notice] = "User #{params[:user_id]} does not have such a registry."
      redirect_to user_registries_path(session[:user_id])
    end
  end

Now, to be clear, I can do a show of the registry normally, and nothing weird happens. It's only when I've added a giftline does the session[:user_id] variable get cleared.

I used the debugger and this is what seems to be happening.

(rdb:19) list
[20, 29] in /Users/kriston/Dropbox/ruby_apps/bee_registered/app/controllers/registries_controller.rb
   20        render :action => 'new'
   21      end
   22    end
   23    
   24    def show
=> 25      @registry = Registry.find(params[:id])
   26      @user = User.find(@registry.user_id)
   27      if (params[:user_id] && (@user.login != params[:user_id]) )
   28        flash[:notice] = "User #{params[:user_id]} does not have such a registry."
   29        redirect_to user_registries_path(session[:user_id])
(rdb:19) session[:user_id]
"tester"
(rdb:19)

So from there we can see that the code has gotten back to the show command after the item had been added, and that the session[:user_id] variable is still set.

(rdb:19) list
[22, 31] in /Users/kriston/Dropbox/ruby_apps/bee_registered/app/controllers/registries_controller.rb
   22    end
   23    
   24    def show
   25      @registry = Registry.find(params[:id])
   26      @user = User.find(@registry.user_id)
=> 27      if (params[:user_id] && (@user.login != params[:user_id]) )
   28        flash[:notice] = "User #{params[:user_id]} does not have such a registry."
   29        redirect_to user_registries_path(session[:user_id])
   30      end
   31    end
(rdb:19) session[:user_id]
"tester"
(rdb:19) 

Stepping on, we get to this point. And the session[:user_id] is still set. At this point, the URL is of the format localhost:3000/registries/:id, so params[:user_id] fails, and the if condition doesn't occur. (Unless I am completely wrong >.<)

So then the next bit occurs, which is

(rdb:19) list
[1327, 1336] in /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb
   1327        end
   1328  
   1329        def perform_action
   1330          if action_methods.include?(action_name)
   1331            send(action_name)
=> 1332            default_render unless performed?
   1333          elsif respond_to? :method_missing
   1334            method_missing action_name
   1335            default_render unless performed?
   1336          else
(rdb:19) session[:user_id]
"tester"

And then when I hit next...

(rdb:19) next
2: session[:user_id] = 
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/filters.rb:618
return index if nesting != 0 || aborted
(rdb:19) list
[613, 622] in /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/filters.rb
   613        private
   614          def call_filters(chain, index, nesting)
   615            index = run_before_filters(chain, index, nesting)
   616            aborted = @before_filter_chain_aborted
   617            perform_action_without_filters unless performed? || aborted
=> 618            return index if nesting != 0 || aborted
   619            run_after_filters(chain, index)
   620          end
   621  
   622          def run_before_filters(chain, index, nesting)
(rdb:19) session
{:user_id=>nil, :session_id=>"49992cdf2ddc708b441807f998af7ddc", :return_to=>"/registries", "flash"=>{}, :_csrf_token=>"xMDI0oDaOgbzhQhDG7EqOlGlxwIhHlB6c71fWgOIKcs="}

The session[:user_id] is cleared, and when the page renders, I'm logged out. >.<

Sooo.... Any idea why this is occurring? It just occurred to me that I'm not sure if I'm meant to be pasting large chunks of debug output in here... Somebody point out to me if I'm not meant to be doing this. >.>

And yes, this only occurs when I have added a giftitem, and it is sending me back to the registry page. When I'm viewing it, the same code occurs, but the session[:user_id] variable isn't cleared. It's driving me mildly insane.

Thanks!

--edit: added session controller code --

Here's the session controller code.

class SessionsController < ApplicationController
  def new
    if session[:user_id]
      redirect_to user_registries_path(session[:user_id])
    end
  end

  def create
    # authenticate now returns user_id rather than user
    if session[:user_id] = User.authenticate(params[:login], params[:password])
      #debugger
      redirect_to user_registries_path(session[:user_id])
    else
      flash[:notice] = "The provided username and password either do not match, or do not exist. Please try again."
      render :action => 'new'
    end
  end


  def destroy
    session[:user_id] = nil
    redirect_to users_path
  end

end

Apart from a "logout" link, the destroy isn't called anywhere else.

A: 

When you say logged out, do you mean that your session user is cleared? You've posted a lot of diagnostic information, which is great, but you're not exposing how your session management occurs.

Is it possible that @user and your "logged in user" are the same variable? If so, it's possible that it might be replaced.

Usually it's preferable to identify one as @session_user and reserve @user as a more general-purpose variable instead.

tadman
I must admit, I've been struggling with trying to figure out what terminology to use where users, registry owners, etc are concerned. I might go back through and change the names to @session_user and @user as you have recommended just for my readability and sanity's sake.But yes, I mean that the session user is cleared. In my code, I have been using `session[:user_id]` to identify if I have a logged in user or not, and in this case, it is being cleared as it is moving off of the last few lines of the show code as I have included right at the top.
Jty.tan
Oh, I'm not sure exactly what you're after when you mean "session management". What can I show that might help?
Jty.tan
If you're using [AuthLogic](http://github.com/binarylogic/authlogic), or a custom-built solution for sessions, then you'd have something in ApplicationController that assigns your user-session variable, whatever that is. It's not clear how session[:user_id] is assigned, and in the examples here it is not modified. You need to define what "logged out" means.
tadman
Yub, I have a Session model that sets `session[:user_id]` on a successful authentication. And there is a destroy command that sets `session[:user_id]` to nil when called. And that's why I'm confused by this issue. It isn't being modified in the code, nor is the session destroy being called, so I don't understand why it is being set to nil after the `default_render unless performed` section of the standard ruby code.I haven't been able to find out exactly what that section of the standard ruby code does either.
Jty.tan
Ok, mildly different question. Is it possible to set `session[:user_id]` to be protected so that only the Session model can change it? (I can't think of a reason why it'd be possible to do so, but I figured it didn't hurt to ask.)
Jty.tan
If you have a Session model, is it created for each request? How does that work when it needs to assign a controller variable? session belongs to ApplicationController, so it is not possible to make it any more private than it already is.
tadman
Ok, I've just added the SessionController code to my original post.The Session code is (in theory), only called when specifically requested, or on a redirect to `new` when there is a page that requires the user to be logged in, and the user isn't.
Jty.tan
This might be a long shot, but is your session identifier changing between requests? I've seen issues in some browsers where, for whatever reason, two session cookies persist and alternate back and forth randomly. Sometimes putting a comment in the HTML that reveals the ID, or putting it in plain text on the page, may be informative. For example: <!-- <%= session.to_yaml %> --> This can help identify issues with the session losing data, or changing entirely. This can happen when you have multiple cookies being applied at the same time (e.g. www.example.com and example.com)
tadman
I've tried this with multiple browsers and across different computers to rule out the issue of the browsers doing dodgy stuff. I've tried the `<%= debug session[:user_id] %>` thing as well (which I think is essentially the same?) and it hasn't helped much. As I said, I can see when the session[:user_id] variable is cleared, I just can't figure out why and what is doing it.I might try a different tack entirely.But hey, thanks heaps for all of the help. If nothing else, you'd helped with cleaning up my code a bit and making it more readable. :D
Jty.tan
If you're having a ton of trouble with your own authentication system, try branching and using a canned solution like [AuthLogic](http://github.com/binarylogic/authlogic) or something similar as that might work better for you. At the very least you can see how someone else has implemented the same thing and seek inspiration there.
tadman
*sigh* After all that, it turned out that I had used an "=" instead of an "==" in an `if` condition in one of the helper functions that was being called in the process of the layout. And it turns out that `next` in the debugger doesn't go into helper functions, which is why it looked like there was nothing in between the 2 sections of code. But as I said Tadman, thanks heaps. After all, it was your suggestion that I consider my usage of "user" and "session_user" that made me come across that mis-typed helper function! Cheers
Jty.tan
I was going to joke that eventually you will find the missing character, but then I thought that'd just jinx you.
tadman