Different Types of Users and User Engine


#1

My question is how have people implemented different types of users in
their Web applications using user-engine?

As for my application, I use single table inheritance in order to derive
several different types of users, such as “moderators,” “editors,” etc

For example, let’s say that I want to create a moderator. I define a new
moderator class and Controller like so:

class Moderator < User
end

class ModeratorController < UserController
end

My problem with this is that since several functions such as “login,”
“signup” and others directly call the User class. I cannot simply
inherit the ModeratorController from UserController without overriding
everyone of these functions and changing every instance of “User” with
“Moderator”

I think there must be a simple and elegant solution to this. Any
suggestions?


#2

Daniel Holmlund wrote:

My question is how have people implemented different types of users in
their Web applications using user-engine?

As for my application, I use single table inheritance in order to derive
several different types of users, such as “moderators,” “editors,” etc

For example, let’s say that I want to create a moderator. I define a new
moderator class and Controller like so:

class Moderator < User
end

class ModeratorController < UserController
end

My problem with this is that since several functions such as “login,”
“signup” and others directly call the User class. I cannot simply
inherit the ModeratorController from UserController without overriding
everyone of these functions and changing every instance of “User” with
“Moderator”

I think there must be a simple and elegant solution to this. Any
suggestions?

If you are using the ‘user-engine’ then you should just create roles
using the engine (role/list) for each type of user. You can then query
a user’s roles if you need to check them for access. You can always
create new columns on the user table if you need to associate more
information.

Do you really need to subclass them?

_Kevin


#3

Well, for example, let’s say that I wanted to extend the user model so
that each user has a GUID associated with them or include a has and
belongs to many relationship with projects.

Roles will allow you assign permissions to particular users so that
actions within the Web application that are allowed or denied, but roles
don’t let you extend the User model.

I suppose I could write a Mixin in order to modify User, but and hoping
to avoid that.

Kevin O. wrote:

Daniel Holmlund wrote:

My question is how have people implemented different types of users in
their Web applications using user-engine?

As for my application, I use single table inheritance in order to derive
several different types of users, such as “moderators,” “editors,” etc

For example, let’s say that I want to create a moderator. I define a new
moderator class and Controller like so:

class Moderator < User
end

class ModeratorController < UserController
end

My problem with this is that since several functions such as “login,”
“signup” and others directly call the User class. I cannot simply
inherit the ModeratorController from UserController without overriding
everyone of these functions and changing every instance of “User” with
“Moderator”

I think there must be a simple and elegant solution to this. Any
suggestions?

If you are using the ‘user-engine’ then you should just create roles
using the engine (role/list) for each type of user. You can then query
a user’s roles if you need to check them for access. You can always
create new columns on the user table if you need to associate more
information.

Do you really need to subclass them?

_Kevin


#4

On Jan 11, 2006, at 10:42 AM, Daniel Holmlund wrote:

moderator class and Controller like so:
everyone of these functions and changing every instance of “User” with
“Moderator”

I think there must be a simple and elegant solution to this. Any
suggestions?

Interesting approach. I haven’t used the login generator yet, but it
seems you’ve got a system that works :slight_smile:

I would add a method to your base class (UserController in this case)
called “user_class”:

protected
def user_class
User
end

Then, in your superclass,

def user_class
Moderator
end

Now, in every instance where you used to reference “User”, change it
to user_class. (e.g. User.new —> user_class.new). The controller
will then be using the correct model in both cases.

Duane J.
(canadaduane)
http://blog.inquirylabs.com/


#5

I have a problem with installing the Engines plug-in
for rails.
I get a
ruby: No such file or directory –
script/plug_in(LoadError)
error when running
ruby script/plugin install engines

Any ideas what causes this problem? I’m upgraded to
1.0 and everything.


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#6

Daniel Holmlund wrote:

I agree with your approach Duane.

Coming from the Java world this is like writing a class getter function.

The only reason I didn’t do this at first was because I was hoping that
I would not have to modify classes that were in the actual user-engine.
so next time there was a new release of the user engine I could simply
check out the next version.

I think I will resort to modifying the User class.

You don’t have to. If you have a user model in your app, the engines
will overload your model. All you have to do is create a user model
with the appropriate function and it should just work.

_Kevin


#7

I agree with your approach Duane.

Coming from the Java world this is like writing a class getter function.

The only reason I didn’t do this at first was because I was hoping that
I would not have to modify classes that were in the actual user-engine.
so next time there was a new release of the user engine I could simply
check out the next version.

I think I will resort to modifying the User class.

Duane J. wrote:

On Jan 11, 2006, at 10:42 AM, Daniel Holmlund wrote:

moderator class and Controller like so:
everyone of these functions and changing every instance of “User” with
“Moderator”

I think there must be a simple and elegant solution to this. Any
suggestions?

Interesting approach. I haven’t used the login generator yet, but it
seems you’ve got a system that works :slight_smile:

I would add a method to your base class (UserController in this case)
called “user_class”:

protected
def user_class
User
end

Then, in your superclass,

def user_class
Moderator
end

Now, in every instance where you used to reference “User”, change it
to user_class. (e.g. User.new —> user_class.new). The controller
will then be using the correct model in both cases.

Duane J.
(canadaduane)
http://blog.inquirylabs.com/


#8

On 1/11/06, jonathan Mcintire removed_email_address@domain.invalid wrote:

I have a problem with installing the Engines plug-in
for rails.
I get a
ruby: No such file or directory –
script/plug_in(LoadError)
error when running
ruby script/plugin install engines

Any ideas what causes this problem? I’m upgraded to
1.0 and everything.

script/plug_in(LoadError)

I believe you’ve typed the script name incorrectly

It should be

ruby script/plugin


Lance B.
http://lance.langwell-ball.com


#9

Isn’t that what I typed? That looks exactly the same
to me…it’s a really odd error.

— Lance B. removed_email_address@domain.invalid wrote:

ruby script/plugin


Lance B.
http://lance.langwell-ball.com


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#10

Can you install any plugins? It would seem this isn’t really an
engines problem - there’s something wrong with your ‘script/plugin’
command…

  • james

#11

If you want to create different ‘types’ of User purely to control
which actions they have access to, you don’t need to subclass User at
all - you just need to create appropriate Roles and assign them to
specific users. As far as I can see, to solve the problem you describe
this is all that is necessary.

To ‘extend’ the User class itself, you just need to create your own
user.rb in /app/models, and include the modules
LoginEngine::AuthenticatedUser and UserEngine::AuthorizedUser. If you
look into the user engine you’ll see that this is all the user.rb file
has in it. You can then add new functionality to your custom User
class as you please. For example, your /app/models/user.rb file:

class User < ActiveRecord::Base
include LoginEngine::AuthenticatedUser
include UserEngine::AuthorizedUser

has_many :projects

def magic_method
puts “this is my custom user model!”
end

and so on…

end

  • james

#12

It looks like you are calling script/plug_in (with an underscore) when
you should be calling script/plugin (no underscore)

Lance

On 1/11/06, jonathan Mcintire removed_email_address@domain.invalid wrote:

I get a
script/plug_in(LoadError)


Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Lance B.
http://lance.langwell-ball.com


#13

On Jan 11, 2006, at 4:10 PM, Lance B. wrote:

It looks like you are calling script/plug_in (with an underscore) when
you should be calling script/plugin (no underscore)

Lance

No, he’s calling script/plugin but the error message he’s getting is
reporting a missing file or directory called script/plug_in (with an
underscore).

plug-in

Lance B.



Lance B.
http://lance.langwell-ball.com


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails

Duane J.
(canadaduane)
http://blog.inquirylabs.com/


#14

That’s what I think…I can install gems but I haven’t
installed a plugin yet.

— James A. removed_email_address@domain.invalid wrote:

Isn’t that what I typed? That looks exactly the

for rails.

http://lists.rubyonrails.org/mailman/listinfo/rails


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#15

Oh, I must have mistyped when writing about my
error…

The error displays “plugin” , not “plug_in”

— Duane J. removed_email_address@domain.invalid wrote:

No, he’s calling script/plugin but the error message

to me…it’s a really odd error.

ruby: No such file or directory –
script/plug_in(LoadError)
http://lance.langwell-ball.com

Duane J.
(canadaduane)
http://blog.inquirylabs.com/


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#16

Daniel Holmlund wrote:

thanks for your help, but my problem isn’t that I can’t extend the User
model to create a moderator or editor, but rather that the
UserControllor specifically instantiates a “User.” if I want to create a
Moderator and a ModeratorController I must override every function
within UserController that uses “User” and the only change I make to the
functions is to replace “User” with “Moderator”

Daniel

Note that the most recent release of the Engines core (1.0.3, I think)
seems to have a minor bug in it. This may be causing your trouble.

_Kevin


#17

thanks for your help, but my problem isn’t that I can’t extend the User
model to create a moderator or editor, but rather that the
UserControllor specifically instantiates a “User.” if I want to create a
Moderator and a ModeratorController I must override every function
within UserController that uses “User” and the only change I make to the
functions is to replace “User” with “Moderator”

Daniel

James A. wrote:

If you want to create different ‘types’ of User purely to control
which actions they have access to, you don’t need to subclass User at
all - you just need to create appropriate Roles and assign them to
specific users. As far as I can see, to solve the problem you describe
this is all that is necessary.

To ‘extend’ the User class itself, you just need to create your own
user.rb in /app/models, and include the modules
LoginEngine::AuthenticatedUser and UserEngine::AuthorizedUser. If you
look into the user engine you’ll see that this is all the user.rb file
has in it. You can then add new functionality to your custom User
class as you please. For example, your /app/models/user.rb file:

class User < ActiveRecord::Base
include LoginEngine::AuthenticatedUser
include UserEngine::AuthorizedUser

has_many :projects

def magic_method
puts “this is my custom user model!”
end

and so on…

end

  • james

#18

There probably isn’t a particularly clean way of doing what you want -
which is perfectly normal, the login/user engines are quite simple,
and not designed to deal with other user classes.

If you think the login/user engines provide the closest
implementation of what you need, I’d suggest you copy it and make all
the modifications that you need locally. You can do this leaving it
running as an engine (probably a good idea if you think you’ll need to
re-use it in more projects), or just re-integrate the
controllers/models/views etc into your own application… and of
course there’s nothing stopping you from releasing what you produce in
it’s own right (with clear documentation of course).

  • james