Need another user model

24 views
Skip to first unread message

Scorpio

unread,
Sep 30, 2011, 9:09:57 AM9/30/11
to Hobo Users
Hi folks, long time no see.
For the record I'd like to mention I'm using rails 2.3.8 (list of gems
below post)

I need to create 2 classes of users with a different signup page. I
got my regular user model up and running but i need there to be a "I'm
a <class1>" "I'm a <class2>" link when one clicks signup and each form
to be under the mentioned links instead of the root/signup

Is it a matter of lifecycle just saying create: signup_user1 and
create: signup_user2 or something like that ?
Thanks in advance



*** LOCAL GEMS ***

actionmailer (2.3.14, 2.3.8)
actionpack (2.3.14, 2.3.8)
activerecord (2.3.14, 2.3.8)
activeresource (2.3.14, 2.3.8)
activesupport (2.3.14, 2.3.8)
hobo (1.0.3)
hobofields (1.0.3)
hobosupport (1.0.3)
mysql (2.8.1)
rack (1.1.2)
rails (2.3.8)
rake (0.8.7)
will_paginate (2.3.16)

Joachim Filip Bartosik

unread,
Sep 30, 2011, 10:14:59 AM9/30/11
to hobo...@googlegroups.com
W dniu 30.09.2011 15:09, Scorpio pisze:

> I need to create 2 classes of users with a different signup page. I
> got my regular user model up and running but i need there to be a "I'm
> a <class1>" "I'm a <class2>" link when one clicks signup and each form
> to be under the mentioned links instead of the root/signup
>
> Is it a matter of lifecycle just saying create: signup_user1 and
> create: signup_user2 or something like that ?
> Thanks in advance

Hello,
I think the easiest way to do what you want is:

1. Use one User model.
2. Add a boolean field belongs_to_class_one to User model.
3. Create a static page for choosing role. Use something like

<form with="&User.new(:is_class_one => true)">
<input type="hidden" name="User[is_class_one]" value="&true" />
<submit label="I'm <class 1>">
</form>

4. Customize form for user, like

<def tag="form" for="User">
<if test="&this.is_class_one">
Form for users in class 1
</if>
<else>
Form for users in class 2
</else>
</def>


Cheers,
Joachim

Scorpio

unread,
Sep 30, 2011, 10:45:25 AM9/30/11
to Hobo Users
Thanks for the idea but what if both classes have different fields and
validations and permitions ? How do I declare that in the fields part
of hobo and lifecycle etc.?

On Sep 30, 4:14 pm, Joachim Filip Bartosik <jbarto...@gmail.com>
wrote:

kevinpfromnm

unread,
Sep 30, 2011, 3:45:05 PM9/30/11
to hobo...@googlegroups.com
You could merge them and just turn off the use of the non-relevant parts, probably easier in the short term but more brittle if you're going to have a lot of user logic (as each method that differs will need to make the check first).

Another possibility would be to keep user as just the core info and have it have associations to 2 models to handle the two cases.

Nothing particularly pretty.  Maybe Matt or Bryan can suggest something better.

Matt Jones

unread,
Oct 2, 2011, 7:16:25 PM10/2/11
to hobo...@googlegroups.com

On Sep 30, 2011, at 9:09 AM, Scorpio wrote:

> Hi folks, long time no see.
> For the record I'd like to mention I'm using rails 2.3.8 (list of gems
> below post)
>
> I need to create 2 classes of users with a different signup page. I
> got my regular user model up and running but i need there to be a "I'm
> a <class1>" "I'm a <class2>" link when one clicks signup and each form
> to be under the mentioned links instead of the root/signup
>
> Is it a matter of lifecycle just saying create: signup_user1 and
> create: signup_user2 or something like that ?
> Thanks in advance

Short version, as I'm trying to get stuff ready for a business trip:

- the recommended way to do this is with STI. Declare the User class as usual, then use it as a base class for the different types. As noted elsewhere, omit the hobo_model declaration in subclasses.

- lifecycles are a bit messy; you can add additional steps to them in subclasses, but removing things currently isn't possible. In the apps where I've done this, the base-class lifecycle typically ended up with just state definitions and some common lifecycle steps (forgot password / reset password)

- you are stuck with a single default lifecycle state for all the subclasses; this is a consequence of using the database to set the default. Not a huge deal, as you can always specify different states in the creator's :become option.

- permissions can be totally separate. If you have common code, 'super' will help.

- some of the automatic account-nav stuff will stop working, or work oddly. In particular, URLs generated for a specific type of user will point to the corresponding controller, not the generic UsersController. This may be a bug or a feature depending on how different the various types are from a UI standpoint.

- if you're using cards, the User subclasses won't get automatically generated ones (they'll use User cards instead). I've just recently fixed this bug in 1.3.

- associations, etc. should all work as expected; you can use the specific types to get type checking for relations that need it. In other words, doing this:

class SomeModel
belongs_to :special_user
end

will raise an error if you try to assign anything but a SpecialUser to it. You do NOT need to use :polymorphic => true to associate a record to a user in general; it's only needed if the classes you're relating to don't share a single table.

- you will need to specify which fields should appear on which page; by default, fields declared in any subclass will appear in all of them. This is mostly a side-effect of STI, since all the models *have* those fields.

- handling the initial location on login: one clean solution to this is to define a method in ApplicationController:

def login_redirect_for_current_user
redirect_path = "/"
case current_user
when Admin then redirect_path = '/admin/dashboard'
when Client
if current_user.accepted?
redirect_path = "/"
else
redirect_path = '/surveys/client_general/responses'
end
when Provider
if current_user.accepted?
redirect_path = "/"
else
redirect_path = '/provider_applications'
end
end
redirect_path
end

(this is an example, your code may be more/less complicated) and then define the login method on UsersController:

def login
hobo_login do
redirect_back_or_default(login_redirect_for_current_user)
end
end

This gets a reasonable behavior - if the user follows a deep-link and isn't logged-in, they get a login page and then are redirected to their destination. Otherwise, they go to the default "start page" for that sort of user.

Hope this helps - if you run into any additional difficulties, don't hesitate to post here or IM!

--Matt Jones

Reply all
Reply to author
Forward
0 new messages