views:

63

answers:

2

I have a website where I need a javascript version of the "current user" object along with the ruby version. I have been assigning these variables doing something like this...

Application Controller:
def get_user
    begin
      @current_user = User.find(session[:user_id]) if session[:user_id]
      @current_user_json = @current_user.to_json
    rescue
      session.delete(:user_id)
      @current_user = nil
      @current_user_json = {}
    end
  end

Web Page:
var current_user = null;
current_user_json = '<%= @current_user_json %>';
if(current_user_json != ''){
        current_user = current_user_json.user;
}

Even when there is a current user, I get the current user is undefined. Probably because I am putting the current_user_json assignment around single quotes. However, if I don't put it around single quotes, I'll always get a javascript error when no user is logged in because the syntax is invalid -

current_user_json = ;

I think I am just looking at this completely wrong and there must be a better way. Given that this is probably a common thing to do, I wanted to get other people's opinion on how to create an object in javascript that is a duplicate of the ruby object.

+3  A: 

JSON is valid Javascript. Consider removing the quotes and just outputting it directly:

current_user_json = <%= @current_user.nil? ? '' : @current_user_json %>;

Better yet, have your controller do all the work instead of putting logic in the view:

@current_user_json = @current_user.nil? ? '{user: null}' : @current_user.to_json 
# ...
current_user_json = <%= @current_user_json %>;

(EDIT: Incorporated Pointy's suggestion below.)

John Feminella
Except for the "nil" case the JSON can't just be empty, or as the question notes there'll be a Javascript syntax error. It should be something like `{ user: null }`.
Pointy
Pointy - your addition made this answer work. Thank you
Tony
A: 

You did not specify where you get your to_json from. If you are using the "json" gem, nil.to_json gives "null", which would produce current_user_json = null in your JS - which is valid. If it's some other library which does not do so, the easiest would probably be to override to_json so it produces valid response:

class NilClass
  def to_json
    "null"
  end
end
Amadan
This is likely not to be a good idea. What if something else depends on the existing behavior of `NilClass.to_json`?
John Feminella
True, something else could break. However, returning an empty string for a null value is likely inconsistent (I suspect `[1, nil, 3]` is serialized as `[1,null,3]` and not `[1,,3]`), and thus a bug which needs fixing. If anything depends on such behaviour, it is almost certainly a hack-around, and thus also waiting to be repaired as soon as the library is fixed. I'd submit a bug report, and fix the library locally until such time as the library gets fixed properly - or use a better library.
Amadan