Query across multiple domain objects in Grails - grails

I am building a "Recent Activity" page just to give some background. Basically this page will be a mash up of several different actions performed by the user. The problem is that this data spans across multiple (3 or so) domain object types all with different fields. All of the domains are associated with the User object but the associations differ.
The domains are UserPost, FriendRequest, and UserTask. Is there a way I can query all these domains, support pagination, and order by dateCreated? Would it be better to change my structure? Any help would be great!

I have implemented similar feature for my web site and I come to the conclusion that it is better to add an Activity domain class that records all kind of activities.
Let's say
class Activity {
Date dateCreated
String linkClassName
Long linkId
def getLink() { getClass().classLoader.loadClass(linkClassName).get(linkId) }
}
Then whenever you insert a new record in your UserPost, FriendRequest, and UserTask (or whatever), you create a new entry in Activity as well using afterInsert GORM events as following:
def afterInsert = {
new Activity(linkClassName: this.class.name, linkId: this.id).save()
}
Once you have done this, you can retrieve your recent activities like this:
def activities = Activity.list(max: 5, sort:'dateCreated', order:'desc')

Related

Override getter in grails domain class for relation version issues

I have an existing application with the following domain classes/relations:
class Contact {
static hasMany = [phones: Phone]
}
I would like to modify the structure to allow for a delete flag to be set in the Phone class and then not have to modify existing calls to the getter for phones to get phones that have not had that delete flag set.
ex:
contact.phones
I have seen a post on this site detailing how to do this.
StackOverflowPost
I have tried that approach(modifications showed below) but GORM is behaving oddly by incrementing the version when it shouldn't be. I'll hit the contact edit page and then when a version comparison is done on the server after submitting the form the version in the DB has incremented up about 5 or 6 times compared to the version value that was passed to the edit.gsp. I have also applied this pattern to two more relations so I'm thinking they are also causing the version to increment. I'm going to test with only one domain relation modification to see if I can find a pattern. Does anyone have any ideas as to the right way to do this or how to avoid version incrementing?
class Contact {
Set<Phone> phones
static hasMany = [phones: Phone]
Set<Phone> getPhones() {
phones.findAll { !it.deleted }
}
}
Not a direct answer to your question, but i use methods in my class, which instead of returning the actual domain instances, returns the detached criteria that callers can use, add new restrictions, and finally get the results.
​class Contact {
DetachedCriteria<Phone> phones() {
def criteria = new DetachedCriteria(Phone).build {
eq "deleted", false
eq "contact", this
}
return criteria
}
}​
The contact class will return a criteria with main restrictions added, and callers can add more restrictions if they have to.
List phones = contact.phones().list()
or
List phones = contact.phones().list {
eq "country", "xxx"
}
This gives callers more flexibility.

Grails/Gorm: how to filter a list of domain objects without affecting the database

Say we have something like the standard Book domain object and bookCategory object. In my controller I want to return a subset of list of books to the view. That subset is not achievable using a find query. When I try to filer the return object, it deletes relationships from the database!
I tried this:
class BookCategory{
String name
static hasMany = [books:Book]
}
class Book{
String title
}
def myController() {
def categories
categories = BookCategory.list()
def user = getCurrentUser()
categories.each { category ->
category.books.removeAll { book ->
!isBookBannedForThisUser(book.title, user)
}
[bookCategories: categories]
}
}
The problem is that it permanently removes these books from the categories for all users from the database!!!
I tried putting the method in a service and using a readonly transaction, but this did not help.
I assume that even if I copy all the categories and books into new list, they will still update the DB as they will still have the book IDs (which I need)
Saving to the database when you dont say save() is very dangerous. is there a way to disable this feature completely?
There is a fundamental flaw in your approach. Do not modify your domain instances if you don't intend to have the changes persisted. Doing so is going to cause you headaches.
Your domain model is suppose to be your system of record. Any changes to it are suppose to be persisted.
If you need to gather up data and manipulate it without having it reflected in your domain model then use a DTO (data transfer object) or similar pattern.
Simply calling .discard() will discard the changes you have made from being persisted when the session automatically flushes.
Instead of working against the framework, and disabling behavior, change your approach to be correct.

Need ideas in designing Domain classes 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.

Grails efficient hasMany-Relationship in View

I'm saving contacts (email, mobile phone, ICQ, AIM etc.) for people like this:
class Person {
static hasMany = {
contacts: Contact
}
}
class Contact {
String code
ContactType type
}
class ContactType {
String name
}
In my view, I've written some Templates for displaying each contact with a select-box for the contact-type and a textfield for the code, spiced up with some JavaScript for adding and deleting.
My question is: Is there an easy and elegant way to update the data similar to personInstance.properties = params or do I have to read out all the fields, deleting removed, updating changed and adding new ones?
I was looking into this some time ago but never got to refactor our code which handles parameters the old-fashioned way.
According to http://www.grails.org/Controllers+-+Data+Binding you can do something like this
def person = new Person(params['person'])
def contact = new Contact(params['contact'])
def conctactType = new ContactType(params['contactType'])
as long as request params are properly namespaced
person.contact.code
person.contact.type.name
You would still have to find out how to handle one to many. Maybe someone who knows can chip in.
Edit:
Came across this doc which describes how to handle one-to-many. It doesn't appear on the main grails site:
http://svn.codehaus.org/grails/tags/GRAILS_DOCS_1_1/src/guide/6.1.6%20Data%20Binding.gdoc

MVC Partial Views, Models and more

I am pretty new to ASP.NET MVC and I am trying to get my head around some of the design concepts at the moment. One thing I am currently stuck on is how (best) to handle a situation such as that described below.
Suppose I have a page that needs to render a number of "sections". For example, on the left hand side there is a list that is data driven and then the selected item in the list displays a further list in another section on the page. For better understanding lets suggest the left hand list is a list of movie categories and the other list displays a list of movies that are contained within that category, along with the various movie details.
Now, I have some form of ORM such as Entity Framework, LINQ to SQL or whatever that maps the tblCategory and tblMovie database tables into Category and Movie entities respectively. These entities live in the MyMVCApp.Data.Entities namespace. I then use a repository pattern located in the MyMVCApp.Data namespace to encapsulate the queries (via LINQ) against these entities to return our model entities.
This is where my first question lies. Should the repository be returning view model entities or domain entities which are then extended to produce view model entities? In my naive mind I see the entities returned from the ORM as simply containers for the data with domain entities containing the business logic. So surely there should be an abstration here?
Anyway, back to my scenario. Now lets assume I wish to present the two sections described at the beginning of this. I am assuming that what should be happening here is my domain entity model would contain a list of categories and their associated movies. So something like a List each of which contains a List.
This model would have been populated somewhere. This is my second question. Say my assumption above is correct and it is simply data entities are returned from the ORM. Now I have a namespace/project called MyMVCApp.Core.Model (or the like) with some domain entities such as the Movie and Category entities mentioned in the previous paragraph. Do these entities have methods on them to retrieve the data from the ORM and populate themselves? Or does the repository retrieve these populated entity models? And another question on this part, if I have a Movie and Customer entity in my ORM is it acceptable to be having domain entities named the same?
Finally, I assume the controller now has this populated list of Category and Movie objects and passes it back to the view. I am guessing it is best to have each of the sections described at the beginning as partial views and passing the populated model to each? So, it may be the IndexController which retrieves the populated CategoryMovies entity, passing this to the Categories partial view and the Movies partial view. I would then need to somehow determine the selected Category (quesrystring?) and display the appropriate list of Movies in that category within the view.
OK, so if anyone has got to this point in my ramblings I will take a deep bow. I hope I have explained my mixed up thoughts and questions in sufficient detail for someone to provide some kind of enlightenment.
Thanks for listening! :-)
Since you didn't mention it, I will assume you are new to DDD concepts. DDD compliments the "M" in MVC by placing logic where it belongs. And, I think a good amount could be applied here.
In strict DDD form, I would use your Movie example as an Aggregate Root (a DDD concept). Within Movie, you would have business logic (methods) that obtain the categories and related entities directly related to Movie (i.e. Categories-this-movie-belongs-in). This assumes the "category" list you want to display is a list of categories this movie is in.
public class Movie
{
private IList<Category> _categories;
public IList<Category> FetchCategories()
{
// you can lazy-load here, use Linq-to-Sql, etc.
return _categories;
}
public void AddCategory(Category c)
{
_categories.Add(c);
}
}
Of course, you can treat Categories as a Value Object (VO, a DDD concept) here if you don't have an identity on them.
Now, what gets more interesting is if you do want to keep an identity on your Categories, treating them as Aggregate Roots with multiple entities and relations to other VOs and alike. In this case, you would want to utilize the DDD concept of Services to combine the two aggregates into your requested Model you want to pass to your Controller. This allows you to create business rules around loading the categories.
public class Movie
{...}
public class Category
{...}
public class MovieCategory : Movie
{
private IList<Category> _categories;
public IList<Category> Categories
{
get
{
return _categories;
}
internal set
{
_categories = value;
}
}
}
public class MovieCategoryService
{
public MovieCategory FetchMovieCategoryByMovieId(int id)
{
MovieCategory mc = _movieRepository.FetchMovie(id);
// do some logic here, some checks, etc
// to obtain your Categories list. Maybe querystring?
IList<Category> cats = ...;
mc.Categories = cats;
return mc;
}
}
The concept is that you now have logic in the domain layer, in this MovieCategoryService, to handle the complex creation of these relationships, or using Factories to create complex types as well.
This gives you a model you can pass around to different View and PartialViews.
The final step in your original post is how to get this into the View. I've been playing with the ViewModel approach to this issue. Creating ViewModels either dynamically, or as a class, and hanging all of the entities on this ViewModel. A recent StackOverflow question hits on this concept. ViewModel Best Practices
I've passed the Model directly into Views, and I am now trying this approach. It does clean things up, as your DOmain Model really should be disconnected from the "logic" on your page. I find myself thinking, "Dang it. I need to get this partialview populated based on this ID. Guess that means another method on the entity." Going the ViewModel approach removes the logic/thinking from the Domain Model, and puts it where it belong - in the Application/UI layer of where you are fine-tuning your view/partialview.
First of all, I think you should just get started with a simple project and try the various scenarios out you pictured in your long question :). There is nothing written in stone, you can use whatever architecture with datalayers and services or whatever, you like !
Or does the repository retrieve these populated entity models?
I would say yes. Your controller graps these from the service and gets them, populated and all and just moves them to the view in order to be displayed.
I am guessing it is best to have each of the sections described at the beginning as partial views and passing the populated model to each?
And again i think you're on the right track ;).
It is a nice idea to give a view model entity to the view instead of the whole domain entity itself thereby providing the view only the required stuffs to work on
First of all return a List of Categories from your Domain, then construct a Movie view which takes the category name as a parameter something like this
- <Host>/Movies/Comedy
- <Host>/Movies/Horror
which would in turn display the movies which belongs to that particular category

Resources