I have a Contact Domain class that can be associated with multiple Organizations, which are also domain classes. I want to use a multiple selection box to allow the user to select the organizations that are associated with the current contact. The selection box is populated with the available organizations. How do I assign the selected items to the organizations list in my Contact class?
<g:select name="organizations.id"
multiple="multiple"
optionKey="id"
from="${com.ur.Organization.list()}"
value="${contact?.organizations}" />
The above is what I am currently trying, and while it does populate the selection with organizations it doesn't seem to put the selected items in my organizations field.
Thanks for any advice.
Edit:
Incorporated comments from krsjunk and omarello.
Here's an abbreviated version of the domain classes.
class Contact{
static searchable = true
static mapping = {
sort "lastName"
}
String firstName
String lastName
.
.
.
static belongsTo = [organizations:Organization, projects:Project]
}
class Organization {
static searchable = true
static mapping = {
sort "name"
}
String name
static hasMany = [contacts:Contact]
}
Well just change the name to
<g:select name="organizations" multiple="multiple"
optionKey="id"
from="${com.ur.Organization.list()}"
value="${contact?.organizations}" />
Should work fine, just tried it.
Note my domain definitions look like this, (just in case you have something different
class Contact {
static constraints = {
}
static hasMany = [organizations:Organization]
String name
}
class Organization {
static constraints = {
}
static hasMany = [contacts:Contact]
static belongsTo = [Contact]
String name
}
one problem is that value="contact?.organizations" should be value="${contact?.organizations}" — not sure if that is the whole problem or not. (also, the attribute multiple=".." is not necessary if value is a collection)
You may also need name="contact.organizations" to be name="contact.organizations.id" and another attribute optionKey="id"
In your newly edit domain example you don't have a one-to-many relationship between contact and organization. You have a one-to-many from organization to contact.
So
value="${contact?.organizations}"
will always be a single item, never a list.
Trying to select/assign multiple organization to a contact will never be valid.
Related
I have created two domain class named City and Address in Grails 3:
class City {
Long id
static hasMany = [addresses: Address]
static mapping = {
id generator: "increment"
}
}
class Address {
Long id
}
I have created two controllers for these classes. The controllers just extend the RestfulController class. I have created the following URL mapping:
group("/api") {
"/city"(resources: 'city') {
"/addresses"(controller: 'address')
}
"/address"(resources: 'address')
}
The idea being that I can access the addresses belonging to a city (with id = 1) via localhost:8080/api/city/1/addresses. Unfortunately, I always get all addresses and not only the ones belonging to the given City. If I break on the index method of the AddressController I see that the params given to the method indclude a cityId which contains the id of the City passed in the query. However, it seems that the id is not picked up during the database query. Am I doing something wrong here? Do I need to add a belongsTo / mappedBy or a City to the Address?
I am new to Grails.
Can I use "hasOne" or "hasMany" without using "belongsTo" to another domain-class?
Thanks in advance.
Yes, you can. See examples in Grails doc: http://grails.org/doc/2.3.8/guide/GORM.html#manyToOneAndOneToOne
hasMany (without belongsTo) example from the doc:
A one-to-many relationship is when one class, example Author, has many
instances of another class, example Book. With Grails you define such
a relationship with the hasMany setting:
class Author {
static hasMany = [books: Book]
String name
}
class Book {
String title
}
In this case we have a unidirectional one-to-many. Grails will, by
default, map this kind of relationship with a join table.
hasOne (without belongsTo) example from the doc:
Example C
class Face {
static hasOne = [nose:Nose]
}
class Nose {
Face face
}
Note that using this property puts the foreign key on the inverse
table to the previous example, so in this case the foreign key column
is stored in the nose table inside a column called face_id. Also,
hasOne only works with bidirectional relationships.
Finally, it's a good idea to add a unique constraint on one side of
the one-to-one relationship:
class Face {
static hasOne = [nose:Nose]
static constraints = {
nose unique: true
}
}
class Nose {
Face face
}
Yes you can, but it behave differently
class Author {
static hasMany = [books: Book]
String name
}
class Book {
String title
}
In this case if you delete Author the books still existing and are independent.
class Author {
static hasMany = [books: Book]
String name
}
class Book {
String title
static belongsTo = [author: Author]
}
In this other case if you delete the Author it will delete all the books pf that author in cascade.
Many-to-one/one-to-one: saves and deletes cascade from the owner to the dependant (the class with the belongsTo).
One-to-many: saves always cascade from the one side to the many side, but if the many side has belongsTo, then deletes also cascade in that direction.
Many-to-many: only saves cascade from the "owner" to the "dependant", not deletes.
http://grails.org/doc/2.3.x/ref/Domain%20Classes/belongsTo.html
yes very easy like a class defintion but only specify hasMany but no need for hasOne
class Student {
String name
User userProfile
static hasMany =[files:File]
}
class User {
String uname
Student student
}
class File {
String path
Student student // specify the belongs to like this no belong to
}
Done!!
I have 2 domain models having many to many relation with themselves
Candidate{
String name
static hasMany = [positions:Position]
}
Position{
static hasMany = [candidates:Candidate]
static belongsTo = [Candidate]
}
my requirement is to fetch the shortlisted status of each candidate for each position, but grails create the intermediate table itself so any idea how to implement it.
Any comments,ideas,examples will appreciated.
If the status is to be stored on the relationship you could create a mapping domain class for the relationship like described in this answer.
The statuses could then be retrieved by (assuming a CandidatePosition class name):
def candidatePositionList = CandidatePosition.findAllByCandidate(candidateInstance)
candidatePositionList.each {
it.position.name // Position name
it.status // Status of candidate for Position
}
I have a User domain class, and a List one.
Each list must have an author (a user) and each user must have a "primary list". Only some of the lists will have the "primaryList" statute.
So.. somthing like
User:
List primaryList
List:
User author
static belongsTo = User
Of course this does not work as intended because the two relations are mistakenly taken as only one. I should also add a hasMany on the User and other belongsTo to the List..., but I don't want to complicate the example because I want to get the right answer from you.
You may need to use mappedBy to explain how the fields in User and List line up. Here are a couple domains that I wrote that allow a User to author many Lists but only set one to be "primary". There are a couple extra nullable constraints so you can use the scaffolded UI without getting into a chicken-and-egg scenario.
class User {
String name
FooList primaryList
static hasMany = [authoredLists: FooList]
static mappedBy = [primaryList: 'primaryOwner', authoredLists: 'author']
static constraints = {
primaryList nullable: true, unique: true
authoredLists nullable: true
}
String toString() { name }
}
I named this class "FooList" just to avoid confusion with the standard List class:
class FooList {
static belongsTo = [author: User, primaryOwner: User]
static constraints = {
primaryOwner nullable: true, display: false
}
}
Try using the map belongsTo approach:
static belongsTo = [user:User]
That way Grails should see the 2 properties as separate.
Have been trying to look for an answer for hours, but have so far not managed to come up with an adequate solution, so I'm hoping someone here might have some more experience with Grails, and implementing custom relationships in it.
My problem is that I have two classes:
Company
OrderConfig
OrderConfig contains two references to Company. 1 for a consignee, 1 for a shipper. I implemented the relationship (see below), and everything looks dandy, with my order_config table containing both a consignee_company_id column and a shipper_company_id column.
However, I do not want or need a company_id column at all. I would prefer using the CompanyName as the identifying column. How can I prevent Grails from automatically adding the id column to the company table, and instead use the companyName column as the primary key, thus ensuring my order_config table will be generated containing the companyName and not the company_id?
I tried embedding the company in the orderconfig class, and wrestled with all kinds of other options including the mappings, however I ran into trouble with each and every one of them.
Thanks in advance!
My code so far:
class OrderConfig {
static hasMany = [consignee:Company, shipper:Company]
String toString() {
return "${consignee}"
}
static constraints = {
consignee (blank:false, maxSize:10)
shipper (blank:false, maxSize:10)
}
Company consignee
Company shipper
}
class Company {
String toString() {
return "${companyName}"
}
static constraints = {
companyName(blank:false, maxSize:10)
companyAddress1(blank:false, maxSize:40)
companyAddress2(blank:false, maxSize:40)
companyAddress3(blank:false, maxSize:40)
companyAddress4(blank:false, maxSize:40)
companyZipCode(blank:false, maxSize:36)
companyCountry(blank:false, maxSize:36)
}
String companyName
String companyAddress1
String companyAddress2
String companyAddress3
String companyAddress4
String companyZipCode
String companyCountry
}
You need to look at the advanced GORM config options in the documentation, in section 5.5.2.1
There is an example
class Person {
String firstName
static hasMany = [addresses:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
addresses joinTable:[name:'Person_Addresses', key:'Person_Id', column:'Address_Id']
}
}
there you can see how they are specifying the key and column name on which to do the stuff.
Edit -- I reread your question: if you are asking how to change it so Company has an assigned id, you might be able to do something like this example
static mapping = {
id generator:'assigned', column:'column_name',name:'propertyName'
}
where more options are available here: http://www.grails.org/doc/1.3.x/ref/Database%20Mapping/id.html