Here is the situation: a user table contains data that overlap with other users' data such as country, age group, gender, etc.
In MySQL, I would use three tables or two. In the case storing country, I would use three tables: one would the be user table, the other country table, and the last one that joins the two. (Of course I could use two tables if one user has one country.)
ex) user(id, otherUserInfo),
userCountry(id_user, id_country),
country(id, countryName)
Being new to Grails, I was wondering what's the best way to represent this schema. Is it necessary to create 2-3 domain classes? Or is there some magical feature (like so many other Grails features (: ) to do this in a single domain class.
More than likely you could do it with two.
class User {
//other user info
//if user only has one country
Country country
//if user has many countries
static hasMany = [countries: Country]
}
class Country {
//country info
}
Since you probably don't want a Country to belong to the User, you don't need anything in the Country class to indicate ties back to the User. Grails/Gorm will handle creating the linking entities in either of these cases.
If the user has many countries and you needed to store other information regarding the relationship you would need to create your own join table. For example if you needed to keep the number of visits the user has made to the country:
class User {
//other user info
static hasMany = [userCountries: UserCountry]
}
class UserCountry {
static belongsTo = [user: User]
Country country
int numberOfVisits
}
class Country {
//country info
}
Related
I'm making an e-learing platform in Grails and I'm not sure how to go about modelling the domain classes. I have the following classes: User, Role (student, instructor, admin...), UserRole and Course.
I want to make it so that every Course belongs to one instructor(User), and every Instructor can have many Courses. But also every student(also User) can be enrolled in many courses. My problem is that instructor and student are both one class (User).
I tried to make it like this by making an additional class Enrolment which keeps record of every student enrolled in each class, but I'm not sure it's ok.
class User {
String username
String password
...
class Course {
String title
String description
static belongsTo = [ instructor : User ]
...
class Enrolment {
User student
Course course
...
I am learning grails and I came up with a use case. In my use case, a product has many users and each user can have many roles.
Here is my product class:
class Product {
String name
String description
String vision
Date startDate
Date endDate
static hasMany = [users : User, contributors : User, watchers : User, approvers : User]
static belongsTo = User
static constraints = {
}
}
Here is my User class:
class User {
static constraints = {
}
String fullName
String email
static hasMany = [roles : Roles, products : Product]
}
Here is the Roles Enum:
public enum Roles {
PRODUCTOWNER ('ProductOwner'),
APPROVER ('Approver'),
CONTRIBUTOR ('Contributor'),
WATCHER ('Watcher')
}
My question is specifically about the association between Product and User. I want to represent the fact that a product can have many users in different roles. Also, each user can be part of multiple products with a different role in each product. Is this the right way to represent this relationship? Also, I should be able to remove and add users to products and vice versa. What this also means is that, users can keep moving between roles and can move in and out of products. In this scenario, I probably don't want cascades to happen. How do I prevent automatic cascades from happening to CRUD operations for this relationship?
Thanks.
I think rather than having roles and products in User.groovy, it will be better if you create a separate domain like UserProductRole. As you said user will have different role in different products then creating a separate domain makes more sense in business usecase and also doing queries
class UserProductRole{
Role role
static belongsTo = [user:User,product:Product]
static constraints = {
user (unique:['product','role']
}
}
You can create composite key but I generally dont perfer it because it makes querying bit difficult.
And now you need to change hasMany in User and Product like following
[userProducts:UserProductRole] rather then having users or products
I want to create a domain class as like , One user can post many orders [Bidirectional] and one order can be liked by many users [unidirectional].
I have written a domain class as shown below ,
Class User {
String userName;
List orders
static hasMany = [Order]
}
Class Order {
String orderId
String orderName
//Indicates this order belongs to only one user
static belongsTo =[owner : User ] // Bidirectional
//Indicates order can be liked by many users
static hasMany = [likedUser : User] //Unidirectional
}
But I am getting am error saying invalid schema . Any body please help...
This post looks similar to my question but I am not getting , Please help.
First, order is a reserved word in SQL. Since GORM by default creates a table with the same name as your class, you'll need to either rename your class or provide a different name to use when mapping to SQL tables.
For example:
class Order {
static mapping = {
table 'user_order'
}
// ...
}
Another problem is that Order contains two associations to User. You need to tell GORM which one of these that is the bi-directional association from User to Order. That can be achieved using mappedBy, like this:
class User {
String userName
static hasMany = [orders: Order]
static mappedBy = [orders: 'owner']
}
Hope this helps.
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.
I am having to two domain classes Order and Stock. When stock is sold I am creating an entry in the child table StockOrder which contains information about the Order(order_id) and Stock(stock_id) and noOfStockSold.
In my current design I coded the StockOrder close to Stock table. You can see this below.
Class Stock {
String stockName
BigDecimal quantity
List stockOrderList
static hasMany = [stockOrderList: StockOrder]
}
class StockOrder {
Stock stock
Order order
BigDecimal noOfStockSold
static belongsTo = [Stock]
}
class Order {
List saleLineItemList
static hasMany = [saleLineItemList: SaleLineitem]
}
Am I doing to correctly from ERP prespective. How to relate Order to Stock sold?
Is it ok if I tie StockOrder to Order also by doing static belongsTo = [Stock,Order]
Is there any better way of doing it or any improvements?
I would start by reading these:
http://grails.org/doc/2.0.x/ref/Domain%20Classes/belongsTo.html
http://grails.org/doc/2.0.x/ref/Domain%20Classes/hasMany.html
Basically you use the belongsTo and hasMany to describe bi-directional relationships. This allows you to cascade delete objects if you so desire. I would imagine in an ERP system that you wouldn't want cascading functionality because if you delete a Stock you probably don't want to delete all the associated StockOrder. I would probably keep the hasMany side of the relationship and remove the belongsTo since you're already associating a StockOrder to a Stock and an Order.