I have the following table schema:
user
-----
id uuid
name string
user_model
------
id uuid
user_id uuid
model_id uuid
role int
model
_____
id uuid
name string
model_no string
I have the following code which fetches the data from the "model" table.
underlyingModel = &model{}
var model IModel
model = underlyingModel
role := 0
db.Table("model").Joins('INNER JOIN user_model ON user.id = user_model.uuid')
.Joins('INNER JOIN model ON user.id = model_id').Find(&model);
In my actual code, the model can be many different struct types with different fields, they're all behind the IModel interface.
What I want to do is to fetch that extra role field from the user_model in one query. Something like .Find(&model, &role).
Is it possible using Gorm?
One possible solution is to create an anonymous struct to put the results in, with a combination of the Select() method.
var selectModel struct {
ID string //I'm assuming uuid matches the string
Name string
ModelNo string
Role int
}
db.Table("model").
Joins("INNER JOIN user_model ON user.id = user_model.uuid").
Joins("INNER JOIN model ON user.id = model_id").
Select("model.id, model.name, model.model_no, user_model.role").
Find(&selectModel);
Basically, you create an anonymous struct with selectModel variable, containing all the fields you want to return. Then, you need to do a select statement because you need some fields that are not part of the model table.
Here you can find more info on Smart Select Fields in form.
EDIT:
Based on additional info from the comments, there is a solution that might work.
Your IModel interface could have two methods in its signature, one to extract a string for the SELECT part of the SQL query, and the other one to get a pointer of the selectModel that you would use in the Find method.
type IModel interface {
SelectFields() string
GetSelectModel() interface{}
}
The implementation would go something like this:
func (m *model) SelectFields() string {
return "model.id, model.name, model.model_no, user_model.role"
}
func (m *model) GetSelectModel() interface{} {
return &m.selectModel
}
type model struct {
selectModel
ID uint64
Age int
}
type selectModel struct {
Name string
Email string
}
Then, your query could look something like this:
var m IModel
m = model{}
db.Table("model").
Joins("INNER JOIN user_model ON user.id = user_model.uuid").
Joins("INNER JOIN model ON user.id = model_id").
Select(m.GetSelectFields()).
Find(m.GetSelectModel());
I'm working on a plain java command line software which performs a recursive LDAP search with Spring LDAP, starting from a specified group and searching all the users from the specified groups and subgroups.
The search fails to find anything if the group distinguished name contains organisational units (=ou), but works in other cases.
Here is the short version of implementation, recursion omitted:
private void searchLdapGroup(List<UserDTO> users, LdapTemplate ldapTemplate, String groupName) {
// recursion guard omitted
String base = groupName.substring(groupName.indexOf(',') + 1);
AndFilter filter = new AndFilter().and(new EqualsFilter("objectclass", "group")).and(new EqualsFilter("memberof", groupName));
List<String> subgroups = ldapTemplate.search(base, filter.encode(), new GroupNameMapper());
// recursive calls for subgroups omitted
getAllUsers(users, ldapTemplate, groupName, base);
}
private void getAllUsers(List<UserDTO> users, LdapTemplate ldapTemplate, String groupName, String base) {
AndFilter filter = new AndFilter().and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("memberof", groupName));
// Paged search omitted.
List<UserDTO> result = ldapTemplate.search(base,filter.encode(),new UserAttributesMapper());
users.addAll(result);
}
The GroupNameMapper returns distinguishedName as Strings and UserAttributesMapper returns user objects from different attributes such as sAMAccountName and givenName.
The code (with recursion) finds all the 36 users in the first test group, where the specified group is like:
CN=import_users,CN=Users,DC=example,DC=test,DC=org
in the same exact test environment it returns zero persons and subgroups when the group distinguished name contains one or more organisational units, such as
CN=import_users,OU=testou,DC=example,DC=test,DC=org
This can't be due to wrong group distinguished name, "memberof" not working or group containing no users, since i tested lookup:
String[] test = (String[])ldapTemplate.lookup("CN=import_users,OU=testou,DC=example,DC=test,DC=org", new ContextMapper() {
public Object mapFromContext(Object ctx) {
DirContextAdapter adapter = (DirContextAdapter) ctx;
return adapter.getStringAttributes("Member");
}
});
which finds
CN=John Doe,CN=Users,DC=example,DC=test,DC=org
and lookup for the user John Doe
String[] test = (String[])ldapTemplate.lookup("CN=John Doe,CN=Users,DC=example,DC=test,DC=org", new ContextMapper() {
public Object mapFromContext(Object ctx) {
DirContextAdapter adapter = (DirContextAdapter) ctx;
return adapter.getStringAttributes("memberof");
}
});
gives results:
CN=import_users,OU=testou,DC=example,DC=test,DC=org
CN=import_users,CN=Users,DC=example,DC=test,DC=org
How come the search does not find anything when organisational units are involved?
Library user:
spring-ldap-core - 2.0.4.RELEASE
The devil is in the details:
The member of the group CN=import_users,OU=testou,DC=example,DC=test,DC=org is
CN=John Doe,CN=Users,DC=example,DC=test,DC=org
But you appear to be searching for users under
OU=testou,DC=example,DC=test,DC=org
That is, it appears all users are under CN=Users,DC=example,DC=test,DC=org, but when you are actually searching for users you assume they are placed relative to the group.
I am using a lead map where the first id represents an Account ID and the List resembles a list of leads linked to that account such as: Map<id, List<Id> > leadMap = new Map< id, List<id> >();
My question stands as following: Knowing a Lead's Id how do I get the related Account's Id from the map. My code looks something like this, The problems is on the commented out line.
for (Lead l : leads){
Lead newLead = new Lead(id=l.id);
if (l.Company != null) {
// newLead.Account__c = leadMap.keySet().get(l.id);
leads_to_update.add(newLead);
}
}
You could put all lead id and mapping company id in the trigger then get the company id
Map<string,string> LeadAccountMapping = new Map<string,string>();//key is Lead id ,Company id
for(Lead l:trigger.new)
{
LeadAccountMapping.put(l.id,l.Company);
}
//put the code you want to get the company id
string companyid= LeadAccountMapping.get(l.id);
Let me make sure I understand your problem.
Currently you have a map that uses the Account ID as the key to a value of a List of Lead IDs - So the map is -> List. Correct?
Your goal is to go from Lead ID to the Account ID.
If this is correct, then you are in a bad way, because your current structure requires a very slow, iterative search. The correct code would look like this (replace your commented line with this code):
for( ID actID : leadMap.keySet() ) {
for( ID leadID : leadMap.get( actId ) ) {
if( newLead.id == leadID ) {
newLead.Account__c = actId;
leads_to_update.add(newLead);
break;
}
}
}
I don't like this solution because it requires iterating over a Map and then over each of the lists in each of the values. It is slow.
If this isn't bulkified code, you could do a Select Query and get the Account__c value from the existing Lead by doing:
newLead.Account__c = [ SELECT Account__c FROM Lead WHERE Id = :l.id LIMIT 1];
However, this relies on your code not looping over this line and hitting a governor limit.
Or you could re-write your code soe that your Map is actually:
Map<ID, List<Leads>> leadMap = Map<ID, List<Leads>>();
Then in your query where you build the map you ensure that your Lead also includes the Account__c field.
Any of these options should work, it all depends on how this code snippet in being executed and where.
Good luck!
Following code is not working.
The error message is "Compile Error: Initial term of field expression must be a concrete SObject: LIST at line 8 column 16" (return line is line 8)
public String getX(){
List<Oppoinvoice__c> o = [SELECT Opportunity__r.Account.Name FROM Oppoinvoice__c];
return o.Opportunity__r.Account.Name;
}
You must specify what entry number of the list must be shown. With your query you will get back a list. And your method must return a string.
public String getX(){
List<Oppoinvoice__c> o = [SELECT Opportunity__r.Account.Name FROM Oppoinvoice__c];
return o[0].Opportunity__r.Account.Name;
}
Or like this:
public String getX(){
String o = [SELECT Opportunity__r.Account.Name FROM Oppoinvoice__c Where Id = 'XXXXXXX'].Opportunity__r.Account.Name;
return o;
}
I require a separate object which contains the related fields of a child object.
Currently I do it like this:
Opportunity opp = [SELECT Id, Name, Account.Id, Account.Name FROM Opportunity LIMIT 1];
Account acc = new Account(
Id = opp.Account.Id,
Name = opp.Account.Name
);
When working with a large related object I have to initialise many more fields than this and the script becomes very large and ugly.
What is the quickest way to initialise the related field data into a separate object?
You must define the all fields in your SOQL query (mor info here).
But it is not necessary if you want to clone the object:
Opportunity opp = [SELECT Account.Id, Account.Name
FROM Opportunity
LIMIT 1];
Account acc = opp.Account;
Example with Custom Object:
Contract__c c = [ Select Account__r.FirstName
From Contract__c
Where Account__r.FirstName != null
Limit 1];
Account a = c.Account__r;