I need help with a design

Colin L. wrote:

On 8 October 2010 03:34, Marnen Laibow-Koser [email protected]
wrote:

involved before thinking about the desired functionality.
I’ll turn the question around: why would you want to consider
implementation before functionality? �What possible benefits could it
produce?

Well of course you need some idea of functionality before anything can
be designed. If I can bring back a quote from your earlier post:

… when I
put together an application, I usually think first about how I want it
to present itself to the user and what the user should be able to
accomplish (and write Cucumber scenarios accordingly). Only as a result
of making those scenarios reality do I write model classes or anything
else.

I am suggesting that there is a phase before considering in detail how
the application should present itself to the user.

There is the phase of deciding in very general terms what the broad goal
of the application is – in your case, something like “people should be
able to order products from us”.

For example to
take the ubiquitous shopping app, before considering how the logon
page should operate there is the decision that there will be users and
that there should be a page where the user can logon.

Sort of. Out of the idea that users can order products comes the idea
that we need a way to tell the system who’s ordering. From that idea
may come the fact that we want user accounts and a login interface.
That’s probably as far as I’d go down that particular path in initial
requirements gathering with my client.

Similarly
before considering how precisely the user adds a product to his
shopping cart there is the decision that there will be products and
shopping carts.

First step: Users should be able to order products.
Second step: We want to present them a shopping cart interface to do so.
Third step: Users should be able to do the following things from that
interface.

The domain concepts emerge from requirements gathering. They are not
considered before it so much as simultaneously with it in my experience.

It is at this stage that initial stabs at what the
models will be can be made (note that I am not suggesting writing any
code here, merely thinking about what the models will be).

No! It’s premature. The business domain objects are a good start for
guessing what model classes you’ll need, but it’s absolutely wrong to be
thinking like a programmer when you’re doing business analysis.

It does
not seem feasible that one can write a Cucumber scenario for user
logon and then go from that to the idea that maybe one needs a user
model.

I assure you, it is entirely feasible. I do it all the time: write a
Cucumber scenario with perhaps only the vaguest idea of what models I
need, then start experimenting with the best way to make it pass.
Remember, Cucumber scenarios are written in English for a reason:
they’re meant to test user-facing behavior, not code. You could
completely rearchitect a system and still have the Cucumber scenarios
pass.

Is it not true that the concept of a User must exist before
one can write the scenario?

The business concept, sure. But it’s premature to translate that into a
concept of a User class in the requirements gathering stage.

(To be fair, user management is simple in most cases and requires a User
class. But I’ve been doing stuff with my medical records application
where I may have a bunch of features gleaned from the client and
translated to Cucumber stories – and still have no idea what the
underlying models should look like.)

Note again that I am not suggesting
writing any code at this time, just thinking about what the models
should be.

And I’m telling you that that’s a bad idea. Don’t think about models
till you actually need to write them.

Colin

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

Colin L. wrote:

On 8 October 2010 13:47, Marnen Laibow-Koser [email protected]
wrote:

There is the phase of deciding in very general terms what the broad goal
may come the fact that we want user accounts and a login interface.
Third step: Users should be able to do the following things from that
guessing what model classes you’ll need, but it’s absolutely wrong to be
Remember, Cucumber scenarios are written in English for a reason:
(To be fair, user management is simple in most cases and requires a User
till you actually need to write them.
I think we are just going to have to agree to differ on this one,

I would rather not do that. In general, that’s a sign that more
discussion is needed, as one or both of us is probably missing
something. Certainly I’m learning a lot from this discussion.

However, I’m perfectly willing to start a new thread for this.

though in fact I do not think our viewpoints are as far
apart as it might appear from this discussion.

Quite probably not. As I think about it more, I do realize that I have
a slight idea about my model class structure at the time I write my
Cucumber stories. But then again, the steps that usually change the
most are the explicitly model-related ones (Given a user exists with
name: “Fred”…)

I also think that you
have to allow a bit of flexibility in approach for the different ways
that different peoples brains work when analysing a system
requirement.

Maybe. I am not at all sure that this is a matter of cognitive style.

Looking back over my career I cannot remember any
instances where I got in a mess or wasted significant time by thinking
about the underlying objects too early in the analysis,

Not to be snarky, but would you really know? It’s easy to do a
premature analysis, get it wrong, and stick with it long after it should
have been discarded. I’ve probably been guilty of this on occasion
myself.

but I can
remember instances of problems when I left this phase too late.

What sort of problems? In general, leaving it as late as possible seems
like the right thing to do.

Of
course the length of my career may have a bearing on what I can and
cannot remember :slight_smile:

:slight_smile:

The one thing that I am sure we can agree on is the importance of
making sure that what is provided is what the user wants, not what you
think he aught to want or what his managers thinks he wants.

Right.

Provided
we achieve that then slight variations in the route to get there are
not so important. Failing to understand the user requirements is the
principle cause of IT system failures I think.

Yes, I would think so, with hacking a close second.

Regards

Colin

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Because you have one user model i have 4, so when i authenticate i have
to
loop all the models to find the credentials beacuse there can be a
company_user with name “pedro” and an admin name “pedro” because they
are 2
diferent models, there is another problem because those 2 pedros could
have
the same password, all because i am using different models for each user
type.

I will not pretend that dealing with these two formidable packages was
without its difficulties, particularly in the the beginning when my
ignorance of them was complete. However, once one grasps the concepts
upon which each is based then elaboration of the resulting security
system is far easier than I ever thought possible.

Oh have use then successfully before and they are quite easy to use, The
problem is i tried out way of using them that is not commun

several points. Authlogic, Devise and similar packages simply identify
a particular set of credentials as having a unique accessor instance in
the system. Declarative_Authorization and CanCan type packages tie
access to specific bits of the application to specific accessor
identities. Both need some form of implementation of the idea of a
session to be of much use.

ryan bates did, it only handles authorization, but all through an
ability
class and to this class you have to pass the user model on
initialization,
but since i have 4
models i need 4 ability class and switch them during login

the application. At some point the need for users will present itself
I agree with this to some point, but i hate refactoring , and i like to
deal with the untested/new/hard stuff first so that if i dont find a
solution with one
strategy i can easily rebuild everything from scratch

Radhames Brito wrote:

Because you have one user model i have 4, so when i authenticate i have
to
loop all the models to find the credentials beacuse there can be a
company_user with name “pedro” and an admin name “pedro” because they
are 2
diferent models, there is another problem because those 2 pedros could
have
the same password, all because i am using different models for each user
type.

Why the hell would you do it this way? Just use one user model with a
role and have done with it. You’re getting name conflicts and other
problems the way you’re doing it…so don’t do it that way!

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

from my fourth comment

I presume that your models are Admin, Owner, User and Client (or

similar names).

yes exactly, but i created separated models because there would be a lot of
conditional validations if i didnt,
for example owners can manage a companies but a user should belong to a
company.

The fact that you worded your initial requirement as

I have pointed out above suggests that these are all Users with
different roles.

yes but i would require different controllers and views for each
roles/type

of user, and what i call user, which is the
company employee in this case, has many roles.

I though about all this before, but the reason i have hesitated to do it

this way is because of the validations, excess in attributes
for the roles/types that dont require them and possible security issues.

I see not way of avoiding the creation of a very fat user model, with lots
of accesible attributes dynamically changing and lots of scopes.

in my fourth comment im explained why i was doing it this way.

Radhames Brito wrote:

from my fourth comment

I presume that your models are Admin, Owner, User and Client (or

similar names).

yes exactly, but i created separated models because there would be a lot of
conditional validations if i didnt,
for example owners can manage a companies but a user should belong to a
company.

The fact that you worded your initial requirement as

I have pointed out above suggests that these are all Users with
different roles.

yes but i would require different controllers and views for each
roles/type

of user,

That doesn’t mean you need different models to go along with them.

and what i call user, which is the

company employee in this case, has many roles.

HABTM roles is perfectly feasible. You might want to use something like
rails_authorization or CanCan to make managing privileges easier.

I though about all this before, but the reason i have hesitated to do it

this way is because of the validations, excess in attributes
for the roles/types that dont require them and possible security issues.

Huh? No. A User is a User is a User, if I understand correctly. Stop
trying to justify a bad design decision.

I see not way of avoiding the creation of a very fat user model, with lots
of accesible attributes dynamically changing and lots of scopes.

There’s nothing wrong with a fat model if it is the best representation
for your data. But I’d be more inclined to use various has_ones for the
additional information.

I’m doing something like this in a medical records app I’m working on,
where clinicians and patients are both Users, but each patient record
also has_one Chart to hold medical information that clinicians don’t
have stored.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

That doesn’t mean you need different models to go along with them.

I wanted to keep the models thiner , but it does not seem to go well
with
authorization and authentication.

HABTM roles is perfectly feasible. You might want to use something like
rails_authorization or CanCan to make managing privileges easier.

Surely i will use is HABTM is im more worried on how to handle company
owners, since they can exist before their companies do
but their employees should only exist after he creates a company, thats
why
i believe ill need a set of controllers and views for
those main roles.

Huh? No. A User is a User is a User, if I understand correctly. Stop
trying to justify a bad design decision.

Im not justifying thats why am here asking you guys because i notice its
a
bad design and to note make a similar mistake again
am asking for advise.

There’s nothing wrong with a fat model if it is the best representation

for your data. But I’d be more inclined to use various has_ones for the

additional information.

Yes colin told me that, but since everything before this project has
been
cleaner and direct i felt like that wasnt the “rails way”

I’m doing something like this in a medical records app I’m working on,
where clinicians and patients are both Users, but each patient record
also has_one Chart to hold medical information that clinicians don’t
have stored.

Very interesting approach, can you explain a bit more, how are you handling
the conditional fields/validations?

I said this before but , the app im trying to build will be like
http://www.shopify.com/ it should allow various scopes of
administration/interaction , that’s why a have an admin,he is in truth
the
site administrator that controls the complete site , the company owner
is
the user that creates an account and pays a subscription fee for each
company they create, what i call the user is a company employee that
works
interacting with that company’s clients and the client is the user to
whom
they give the service.

On 8 October 2010 14:56, radhames brito [email protected] wrote:

[…]
Because you have one user model i have 4, so when i authenticate i have to
loop all the models to find the credentials beacuse there can be a
company_user with name “pedro” and an admin name “pedro” because they are 2
diferent models, there is another problem because those 2 pedros could have
the same password, all because i am using different models for each user
type.

I am sorry to have to point out that the route you have gone down here
supports Marnen’s contention that model definition should not be
started till the operational requirements are known. I imagine in
your original spec you would have specified a single logon page (not
four different ones). This is a clue that all the different types of
users should be of the same (or derived) types.

:frowning:

Colin

On Fri, Oct 8, 2010 at 11:18 AM, Colin L. [email protected]
wrote:

type.

Yes i see, the idea come after checking out how devise handles roles in
their examples, devise uses a sort of scope and roles can be
different models, so i figure using this appreach would let me avoid the
creation one big fat user model, but it didnt work as expected.
Just take a quick look at devise and you will see where the idea come
from.

Colin L. wrote:

On 8 October 2010 14:56, radhames brito [email protected] wrote:

[…]
Because you have one user model i have 4, so when i authenticate i have to
loop all the models to find the credentials beacuse there can be a
company_user with name “pedro” and an admin name “pedro” because they are 2
diferent models, there is another problem because those 2 pedros could have
the same password, all because i am using different models for each user
type.

I am sorry to have to point out that the route you have gone down here
supports Marnen’s contention that model definition should not be
started till the operational requirements are known.

Haha! Resistance is futile. You will be assimilated.

[…]

:frowning:

Colin

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Radhames Brito wrote:

Because you have one user model i have 4, so when i authenticate i have to
loop all the models to find the credentials beacuse there can be a
company_user with name “pedro” and an admin name “pedro” because they are 2
diferent models, there is another problem because those 2 pedros could have
the same password, all because i am using different models for each user
type.

From what I have read I suggest that you reconsider what exactly a user
is, what data is specific to a user and what data is specific to certain
classes of users. It seems to me, taking your statement above as a
guide, that you are confused as to the actual arrangement of things in
the real world.

First, there is, and can only every be, one real person with the
identity ‘pedro’. There might be many people with similar names who are
also known to your system but they are all different individuals. In a
computer system, indeed in any organized filing system, some method of
distinguishing between individuals other than by common name is
required. Thus User IDs, SSNs, SINs, IRS IDs and so forth. Whatever
the case, a given individual should have only one identity in a system
and a single system identity should only ever refer to one individual.

Second, the attributes of a company belong in something that is related
to that society in its own right and not to any individual associated
with it.

Third, the user membership of a society is a separate issue as well.
Consider that userid pedro might work for two companies at once. Or
might work first for one company and then for a different company. This
is an association or state that is distinct from either the user or the
company even if it is dependent upon both.

In a similar fashion, user pedro might have superuser privileges for one
company but only user privileges for another. As I understand your
proposal this person would require an entry with one userid in the
company-admin model and another in the company-user model and possibly
even more entries for different company-user or company-admin model
combinations. This is a maintenance nightmare that you are creating.

If instead you look at this from the point of view of entities and their
relations then resulting data structure will be much more natural and
will be easier to work with. So something like:

User 1—n CompanyUser n—1 Company plus
CompanyUser n—n UserRole n—n Role n—n RoleRight n—1
Right

Is likely a more flexible way to obtain the requisite functionality. If
you go with AuthLogic and Declarative Authorization then after these are
wired into your app all you are left to implement with respect to RBAC
is in essence just:

Company 1—n CompanyUser n—n UserRole

Which strikes me as a bit more manageable.

Devise is an authentication system. The fact that it can be used to
implement a primitive two-tier authorization system is a convenience for
web apps that do not require a finer-grained approach to RBAC and wish
to avoid the overhead of a full-featured RBAC implementation. I cannot
see Devise’s authorization functionality dealing with anything very
elaborate for the reasons that have been discussed at length in this
thread. Namely, it either requires a separate User model or a separate
User attribute for each and every role.

The bottom line is that you have asked for advice. The advice that you
are getting is uniformly against your chosen path. That is not to say
that our advice is perfect or that your approach will fail. However,
that seems the way to bet at the moment.

The bottom line is that you have asked for advice. The advice that you
are getting is uniformly against your chosen path. That is not to say
that our advice is perfect or that your approach will fail. However,
that seems the way to bet at the moment.

oh and i appreciate your advice very much, apparently every time i
explain
why i choose that path at the beginning readers think im jutifiying it,
there is a confusion im not saying that the way i started is a good way
, no
no no, that design gave me a head ache but before refactoring i wanted
to
make sure the other options i was going to try wasnt wrong too (now im
gona
start with the features first and will create one user model with HBTM
roles).

There seems to be some confusion, i was convinced that my first
approach
was is wrong since like the third reply you guys gave. Right now i just
want
to know if anyone has had a similar problem and can give me any tips.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs