Need ideas in designing Domain classes Grails - grails

I am learning Grails, I am trying to build a small application. And for now I am working on the registration part.
There are 3 different views for registration process
1) As an employee my registration view is different with different fields
2) As an employer registration view would be different where I would be collecting company details, an authorized representative who can act on behalf of the company. So as a matter of fact I was thinking that company(employer) is not the actor but representative is an actor and hence need a representative domain class.
3) retailer registration view is different.
So I need to define the domain classes and its relationships I am very much new to grails and I need some guidance in designing
I was initially thinking of User domain class and have UserTypes(which defines different types of users ex. representative,retailer and employee) but not sure if that works.
Appreciate if someone could help me in building my domain classes.
Thanks

You definitely want to map out your domain classes before you start working on the views. Is the authorized rep always going to be an employee, or is it a completely different entity?
Think of it in terms of objects, and try to mimic it as much as possible. A company has employees, and can have an authorized representative. Here's a sample mock up:
class Employee {
String firstName, lastName /* etc... */
}
class Company {
String name /* etc */
Representative authorizedRepresentative
static hasMany = [ employees : Employee ]
}
class Representative {
}
Of course, you may want to have references from the Employees back to its Company. Have a look at the Object Relational Mapping portion of the Grails docs.

Related

GORM - Model Relationships Between Like Entities

For my project I'm using Grails, but this is kind of a general ORM question.
I'm new to ORMs and ER diagrams, and trying to figure out how to best describe/implement the following:
I have 2 Entities: User, Connection
A Connection consists of 2 Users (and other primitive attributes). A user can be found in more than one Connection. How would you describe the relationship between User and Connection? I don't know what you would call it, 2 to many? How would you draw it in an ER diagram.
In GORM, should it be a bi-directional relationship?
Edit
As an added requirement, assume the users have specific roles in the relationship. Like student and teacher. So Connection would have student and teacher properties of type User.
the problem is not GORM, your problem deals with Entities. Before you code Domain classes, you have to image distinctly what info you would like to keep and operate. According your question and comments you prefer to use any RDBS. So let's to try to image easy simple tables (don't care about any ORM, Grails, bi\uni-directions) and try to fill this tables mock details.
Users
nickName (String)
otherUsersFields
Connection
teacher (Users)
student (Users)
otherConnectionFields
well, now we know all Users and all Connections. For given connection we can say who is teacher - connection.teacher and student - connection.student.
Note: any Connection has only two users.
pay attention to Users. Any User can be Student and Teacher. If User can be only Student or Teacher you will have to add additional field(s), for example
Users
nickName (String)
isTeacher (boolean)
otherUsersFields
now we have a list of user and know who is st. or tech.
How can I get all connections for given user?
GORM offers: Connection.findAllByStudent( givenUser), Connection.findAllByTeacher( givenUser)
Do this tables show your info completely?
I think what you want can be described as a many-to-many relationship, with some sort of constraint applied on Connection users collection. As for uni/bi-directional, I believe you can accomplish either depending on your use case - although uni-directional is probably harder to map/configure.
I haven't tested this, but a bi-directional many-to-many should look like this
class Connection {
...
Set users = [] //ensure users exists, constraints won't work on null
static belongsTo = [User]
static hasMany = [users: User]
static constraints = {
users maxSize: 2
}
}
class User {
...
static hasMany = [connections: Connection]
}
I don't have a uni-directional example off the top of my head, but I believe you may need to use an additional mapping class.
Again, I haven't tested this, but here's an example of uni-directional many-to-many with a mapping class
class Connection {
...
Set users = []
static hasMany = [users: ConnectionUser]
static constraints = {
users maxSize: 2
}
}
class User {
...
}
class ConnectionUser {
User user
Connection connection
//or for cascading effects
//static belongsTo = [connection: Connection]
...
... //lots of additional code to manage adding,
... //removing, updating Connection-to-User relationships
}
Connection knows about Users, but Users do not know about Connections they belong to. If you go the mapping class route, you'll need to manage the Connection to User relationships manually. Take a look at Spring Security Core PersonAuthority class for an example of mapping class.

Grails adding attributes to one-to-many relationship

I have set up a one-to-many relationship in my scaffolded Grails application:
class Course {
County county
Date date
int maxAttendance
static hasMany = [ persons:Person ]
}
class Person {
String firstName
String lastName
String email
Course course
boolean attended
boolean paid
static belongsTo = [ class:Course ]
}
So, when a user views the CourseController, they are able to see Person's registered in the selected Course.
My question is, how can I change the application so that when a user views the people in a given course, they can also view/modify the checkboxes for 'boolean attended' and 'boolean paid', which are also in the Person domain? Here is a screenshot:
The thing is that you are using the scaffolded view, so you are pretty much stuck with the default design.
You can modify the behaviour, by installing and modifying the templates that grails uses to generate those views:
grails install-templates
This will create the templates in src/templates/scaffolding, although I do not recommend that approach. Maybe it is time that you start developing your own controllers and views, since the scaffolding is there mainly for testing and for administrative use.

How do I use JAXB types as Grails domain classes?

My system consists of a back-end part, written in Java, exposing a set of web services which are defined contract-first using WSDL and XSD. Among the data transported over the web services are a large set of product types (they are different kinds of bank accounts, to be precise). Our front-end is a Grails web application. It uses and exposes the data and operations hosted by the back-end. The front-end has no database on its own for security reasons; all data is stored on the back-end. Pretty standard architecture.
Now, the set of products is large, growing, and volatile. Each product type has to be CRUD-ed on the web application user interface. It would be lovely if I could tell Grails to use the XSD specifications of the product types as domain types, and generate views and controllers for them.
I have not found a solution for this puzzle yet, even after extensive experiments and lots of web browsing. I have about a year's worth of professional experience with Grails. Any help or ideas would be appreciated.
Some details:
A product type is a simple POJO data carrier. Some simplified examples:
package jaxbgenerated;
public class Product1 {
protected Account from;
protected Account to;
protected String name;
// + getters and setters
}
public class Product2 {
protected List<Account> accounts;
protected String name;
// + getters and setters
}
public class Account {
protected String id1;
protected String id2;
// + getters and setters
}
Note that "Account" is not a product type but it is a JAXB-generated type. Products can contain such in addition to properties of simple data types like String, int and Date but they never contain other product types.
The end result I am aiming for is a Grails-generated form where a user can edit a Product1 instance with nested forms for editing its constituent Accounts. And likewise for Product2.
My idea is to first manually code a Grails domain class for each JAXB-generated type:
//in grails-app/domain:
 
import utilities.Copier
 
class Product1 extends jaxbgenerated.Product1 {
Product1(jaxbgenerated.Product1 jaxb) {
Copier.copy(jaxb, this)
    }
static constraints = {
}
}
There is a bit of boilerplate code here but nothing more than I can live with. The Copier.copy() function is (I think) needed to convert a jaxbegenerated.Product instance fetched from the back-end to a Product1 instance which can be used in Grails. It recursively looks for jaxbgenerated properties in the jaxb source, and copies their values to the corresponding Grails domain type. The constructor is invoked from a layer that fetches data from the back-end.
I can use the constraints block to manually add semantic constraints where needed, e.g. that the "from" and "to" accounts are not the same.
Next, I generate controllers and views for all the Grails domain classes thus constructed, and run the application. And get a stack of exceptions:
Caused by MappingException: Could not determine type for: Account, at table:
product1_type, for columns: [org.hibernate.mapping.Column(from)]
I think the trouble here is that Product1's "from" and "to" properties are not of type Account but of type jaxbgenerated.Account.
I have tried different approaches but to no avail. Some notes:
As I said, all data storage happens on my back-end, so I do not need
the GORM/Hibernate aspect of Grails. Therefore I tried adding
"static mapWith = "none" to the domain classes but that did not
help.
I tried explicitly telling Hibernate the type of the Accounts
in Product1 by adding "static mapping = { from type: Account }" but
that did not work either.
Any help or ideas would be appreciated.
/Jan Reher, Systematic A/S, Denmark
I think you have do write a dababase plugin similar in concept to this simpledb

Basic programming with MVC

Wanna get views on a very basic structure as follows:
"Person lives inside town ABCTown. ( ABCTown consists of "Person" visually). And "Person" has information about town ABCTown", ie. he has knowledge about his town.
That's all .
A very basic approach would be making two classes Class_Person and Class_ABCTown . And exchanging references of each other.
public class Class_ABCTown
{
var person:Person ;
.....
.....
public function get personInfo()
{
return person.info() ;
}
}
public class Person
{
var abcTown:ABCTown ;
....
....
public function get townInfo()
{
return abcTown.info() ;
}
}
Now as a programmer, i want to extend the project more towords MVC design pattern. So what do you think, what classes can i add here, and how can i arrange them, to get a MVC design.
( For example Class_ABCTownView can be created to store the reference of PersonView, because visually, person is present inside the town )
Share your views.
Thanks
"Person lives inside town ABCTown. ( ABCTown consists of "Person" visually). And "Person" has information about town ABCTown", ie. he has knowledge about his town.
Based off of this I'd create a Person Class, a Town Class and have them consists of a One-Many relationships (one town can have many people). This is all that is needed for the model.
The Controller is sort of like a pointer that directs all user input to the correct action (so if you click the details button the controller will direct the application to go to the view page and display the model).
The view page essentially is used to display information and forms.
If you want an action to happen such as a person moving to a town, you can put in an Edit action for example in the Person Controller to edit information about a person such as which town they live in. This will cause the application to go to an edit view where users can make changes.
This is a well-known tutorial that teaches you what MVC is and how to use it: http://www.asp.net/mvc/tutorials/mvc-music-store
I think you are misunderstanding the MVC pattern. The code above represents the M part of MVC - the data Model. The V (View) would be the classes, JSPs, etc that present the information to the user, and the C (Controller) is the code that handles user interaction, retrieves the data model from persistence, updates the model, binds the model data to the View, etc.

Extending a member profile with two further layers - asp.net mvc

I have a modeling question related to profiles. Firstly, I have looked into using the SQLTableProvider and using the in built profiling system but didn't feel they were suitable. So, with that said, I have a membership scheme where every person has a profile, then that person can upgrade their profile to either an individual (additional fields) or a company account (additional fields again).
So I thought, use a Profile base class and then inherit from that for the Company account and Individual account. However, when it comes to implementing this in MVC I'm hitting a brick wall.
Since either the company or individual edit pages are effectively updating both the base Profile table and also the individual/company tables from the same page. How would I go about implementing this within the model (which is currently generated via LinqToSQL) and also at the view level?
Apologies if that wasn't very clear, tricky one to explain!
If you are using Linq to SQL, then you already have a model. Linq generates the entities and collections based on your database for you. The generated model is a shallow one, but is pretty solid and workable. The Linq to SQL model can be extended via partial classes allowing you to enhance entities or the context itself for additional functionality.
The controller can work directly against the generated model and pass entities or collections of entities to the view as needed.
I would suggest that, for what you appear to be trying to do, you might consider not using the built-in profile provider system at all. The profile providers in asp.net work well for simple personalization stuff, but it doesn't work well for concrete data like contact info and such. Also keep in mind that the profile provider systems tend to store object data as serialized strings in the database... this makes getting at profile data very difficult from admin tools and such. Performance starts to become a problem VERY fast in any case where you are needing multiple user's profile information (such as with an admin user editor).
For a when you are storing important personal details like the stuff you mentioned, what you are really storing are "account details" not "user profiles". You can extend a membership provider to expose your additional details, but I've generally found it much easier to just roll my own data model and access logic to deal with the additional account information.
My rule of thumb is this: if the information is ONLY needed during a request made by the user to whome the data belongs, then it goes in profiles. If I would need the data for one user to be read during another user's request, or if I would need a "list" of that data for different users, then it doesn't go in asp.net profiles.
Do you mean settings like choosing how many items to view on each page, and choosing some style sheet?
public class Profile
{
int? ItemsPerPage { get; set; }
string PreferredStyleSheet { get; set; }
}
The company selects some values that will work for users unless the users have chosen some other values for themselves. Is that what you have in mind?
In that case: I don't know how to do it together in ASP.NET Profile, but how about the following tables in the database:
TABLE Setting
(
SettingID int NOT NULL,
SettingName varchar(32) NOT NULL,
DefaultValue nvarchar(128) NULL
)
TABLE CompanySetting
(
CompanySettingID int NOT NULL,
RefSettingID int NOT NULL,
RefCompanyID int NOT NULL,
SettingValue nvarchar(128) NOT NULL
)
TABLE UserSetting
(
UserSettingID int NOT NULL,
RefSettingID int NOT NULL,
RefUserId uniqueidentifier NOT NULL,
SettingValue nvarchar(128) NOT NULL
)
And then make some joins for the present user. If the user setting is not given, take the company setting; if the company setting is not given, take the default value.

Resources