This a continuation of this question.
I have an Address
class which contains basic street address information. I also have a User
class which has the attributes physicalAddress
, mailingAddress
, cargoDestinations
, and cargoSources
. The User
class looks something like this:
class User {
String username
String password
String firstName
String lastName
String businessName
String phoneNumber
Address physicalAddress
Address mailingAddress
static hasMany = [accounts:Account, cargoSources:Address, cargoDestinations:Address, cargoes:Cargo, loadsLogged:Load, loadsDelivered:Load]
Set accounts, cargoSources, cargoDestinations, cargoes
static mappedBy = [loadsLogged:"loggedBy", loadsDelivered:"deliveredBy"]
//some other stuff after this
And the Address
class looks something like this:
class Address {
static belongsTo = [user:User]
String streetAddress
String city
String state
String zip
BigDecimal taxRate
//some other stuff after this
I followed the tutorial here for the most part. In step 5 my template looks like this:
<g:select
from="${account.user.cargoDestinations}"
name="cargoDestinations" value="">
</g:select>
The problem is that instead of returning only cargoDestinations
, the template returns ALL addresses associated with that user. If I change from="${account.user.cargoDestinations}"
to from="${account.user.physicalAddress}"
or from="${account.user.mailingAddress}"
I get the expected result, so I know my problem has something to do with how the cargoDestinations
variable开发者_如何转开发 is mapped. How can I go about fixing this without changing my class files too much?
The way you have your addresses mapped, they all link back to the user on the user_id column. You'll need to add some fields to Address to distinguish how they're related to User, similar to how you've mapped Loads. For example:
class Address {
static belongsTo = [cargoSourceFor: User, cargoDestinationFor: User]
...
}
class User {
...
static hasMany = [cargoSources:Address, cargoDestinations:Address]
static mappedBy = [cargoSources: "cargoSourceFor", cargoDestinations: "cargoDestinationFor"]
...
}
If you're familiar with SQL, doing a grails schema-export
and looking at target/ddl.sql
can be helpful when setting up mappings.
I ended up adding several boolean fields to my address class, which made the design simpler and much easier to work with. This way I only need one class instead of several nearly identical classes. The boolean fields in the Address
class now indicate if an address is a physical address, mailing address, cargo source, etc., or all of the above. As @ataylor pointed out, this system makes it so an address object can only be associated with one user from my User
class, but it does not seem like that will ever be an issue. The worst case is that a multiple users would have the same address in real life, and my program would require the creation of a separate address object for each of those users, even though the addresses in question would be identical.
精彩评论