Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would one implement this sort of gradual engagement/lazy registration in Rails?

A long time ago I ran into a website (I unfortunately lost the address, it was some kind of newspaper site) that allowed you to make use of everything as if you were a registered user. You could rate, favorite and comment articles, and when you did it would display a discreet, embedded message saying you had to register to the website for your contributions to be saved. Then it had the link for you to see how your profile would look like if you did, and I was surprised to see it had all my activity there; the articles I read and saved, comments, etc. I left the site and when I came back to it later just out of curiosity, it still had my activity saved.

I thought it was the greatest thing ever, and now that I am in the process of building a website with social features, I would like to take that approach as well. But I am still pretty much a noob and so I don't have much clue as to how to go about it. How would you do it?

like image 341
San Diago Avatar asked May 27 '09 21:05

San Diago


2 Answers

I would create a Profile model which is automatically created for any user that visits your site and adds the first favourite, rates the first item, etc. The Profile should be saved to your database including a suitably random and unique string. This string can be stored as a cookie on the client side, and will be used later to retrieve your profile. It should be random and long enough so that you cannot easily tamper with your cookie and get other anonymous people's profiles, but this is not entirely avoidable (so beware you store no sensitive data in anonymous profiles!).

Once a user registers, you can associate their Profile with their new User record and remove the cookie and the unique string identifier. You can now simply retrieve their profiles when they log in, based on their User record.

The Profile model can contain any information you would like to store.

If you want to differentiate between registered users and anonymous users, you could create an AnonymousProfile model and a Profile model (each with different attributes), and simply copy over all data from the anonymous profile to the user profile when someone registers.

Update: Throughout your application you can decide to only use this information when a user is logged in. You might define a before_filter that grabs the current user, and only if there is an actual user logged in, do you use the profile data:

class ApplicationController < ActionController::Base
  before_filter :fetch_user_data

  def fetch_user_data
    @current_user = ... # Work your magic to get current user
  end

  private

  def current_profile
    @current_user and @current_user.profile  # Use profile association
  end
end

Somewhere in a controller action:

if current_profile
  # Do stuff with current_profile
  # Only available to registered users...
end

You can later change the implementation of current_profile if you change your mind and want anonymous profiles to have effect for your anonymous users.

like image 129
molf Avatar answered Sep 21 '22 20:09

molf


The only way to identify users is to use cookies. What the site you were using is likely doing is:

For a first time user create an entry in the 'users' table and add them to the 'guests' group. Save down an identifier cookie to the users machine so you can look them up again later.

If the user decides to register you can fill out the rest of their details in the user table (you might even want to have a separate table for user details and registration details like username/password etc...) and add them to the registered users group.

The way you manage your groups can be as simple as a flag in the database.

As this is a rails question...

I would probably handle most of this in a before_filter in your application_controller.rb. The steps would be something like:

if has_cookie
   @user = lookup_user
else
   @user = create_new_guest_user
end

You could very easily extend one of the existing authentication frameworks like acts_as_authenticated or clearance to do this.

like image 23
jonnii Avatar answered Sep 21 '22 20:09

jonnii