I want to add a property to my User model that returns the number of rows in the Project table that have a user Id of the user.
So something like this...
def numProjects = {
/* somehow get count from Project table
The straight sql would be:
SELECT COUNT(*) FROM projects WHERE userId = <the current user>
*/
}
According to the documentation here (found here), assuming you're looking for the project count for a User of id 1234 and assuming that your Project model inherits the MetaMapper trait (probably through KeyedMetaMapper), it seems you can use the count method as such:
Project.count(By(User.id, 1234))
or
Project.count(BySql("userId = ?", 1234))
I can't test because I haven't used Lift yet, but it looks right... :) Let me know if it works!
Related
I ran across this Apex Trigger code that I don't quite understand...
Id is, of course, an Id
hId is a SET
I would normally expect
"WHERE Id IN :hId", instead of
"WHERE Id = :hId"
trigger linkHusbandAndWife on h2w_c (after insert) {
Set<Id> hId = new Set<Id>();
for (h2w_c h2w : Trigger.New) {
hId.add(h2w);
}
List<Husband_c> husbandlist = [
SELECT Id Wife_Id
FROM Husband_c
WHERE Id = :hId
];
...
}
Question: How can "Id = :hId" when hId is a SET?
Is this somehow equivalent to "Id IN :hId" ?
Yes, the syntax for queries written in Apex is quite forgiving. Especially normal SOQL (written in [brackets], not the dynamic SOQL where you craft query from Strings) . It's more of Apex feature than SOQL, you might have been looking in wrong reference guide. The magic is in "bind variables" (:) and you can't always use same trick when making raw query via API for example.
WHERE Id = :collection is fine. Collection being a single variable of type Id, a Set or a List.
WHERE Id IN :collection has same result. And you don't even need parentheses!
This means your query can ditch the intermediary step of making a Set, less code to write:
SELECT Id, Wife_Id__c FROM Husband_c WHERE Id IN :trigger.new.
A List<sObject> will be silently "cast" to List<Id> for purposes of SOQL. I used quotes because normally you can't cast it, a sObject will never be an instance of Id. If you'd need similar behaviour in normal code you'd need something like Set<Id> mySet= new Map<Id, sObject>(mylist).keyset();.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_variables.htm
https://developer.salesforce.com/forums/?id=906F000000090b1IAA
https://salesforce.stackexchange.com/questions/17695/how-do-i-build-a-soql-query-for-records-in-a-list-of-ids
OK, recently I am implementing an RBAC based system in laravel.
I have these two classes as my models:
class User extends Authenticatable
{
public function roles(){
return $this->belongsToMany(\App\Role::class, 'user_role', 'user_id', 'role_id')->withPivot('is_expired', 'assigned_at', 'expire_at');
}
}
class Role extends Model
{
public function users(){
return $this->belongsToMany(\App\User::class, 'user_role', 'role_id', 'user_id')->withPivot('is_expired', 'assigned_at', 'expire_at');
}
}
it works fine BUT, I want to set a default value for the expire_at attribute of the pivot table based on an attribute of the Role model. for example I have a period attribute on Roles table, and its a number representing number of months.
So i want when a role assigned to a user (inserted in pivot table) the value of expire_at set to currentDatetime + thePeriodNum months and save in the pivot table.
how can I achieve this?
I have tried laravel custom pivot class and mutators but it seems not working or I did something wrong.
somebody mentioned that the mutators dont get triggered when using attach()/detach() methods so I think even if it was working i could not see the difference.
Someone mentioned its possible with observers but I have no Idea what is an observer im noob.
So thats all, it would be really good for me if anybody could help me through this mess I'm in right now.
Thanks in advance.
It is possible to attach the new role and set the expires_at column at the same time. This would avoid needing to use observers (listeners of model events) within your code.
The code would look like the following:
$role = Role::find($roleId);
$expireAt = now()->addMonths($role->period)->toDateTimeString();
// or Carbon::now()->addMonths($role->period)->toDateTimeString();
User::find($userId)->roles()->attach($role->id, ['expire_at' => $expireAt]);
Here, the role is found. A timestamp is created by taking the current time, adding the addition months based on the role's period (this should be an integer value).
Finally, this is added to the attachment of the role to the user.
Add as a model method
This can all be added as a function/method on the User model which would clean up the code into one action, ->addRole($roleId):
// Within App\User.php
public function addRole($roleId)
{
$role = \App\Role::find($roleId);
$expiresAt = now()->addMonths($role->period)->toDateTimeString();
$this->roles()->attach($role->id, [ 'expire_at' => $expiresAt ]);
}
This can then be called with the following:
$user = User::find($id);
$user->addRole($roleId);
I hope this help.
i am trying to make a simple selection in a wordpress table (created by a plugin). the table is named reduceri , and has the following columns: id, post, category.
so, i am trying to take all the category values, when the post is equal to the current post id.
the way i am doing the query is:
$the_query = "
SELECT $wpdb->reduceri.category
FROM $wpdb->reduceri
WHERE $wpdb->reduceri.post = ".$post_id."
";
$my_reduceri = $wpdb->get_results($the_query);
but when i var_dump the $my_reduceri all i get is an empty array: array(0) { } even though there should actually be some results... any idea where i am wrong (in the query)?
thank you
Did you declared global $wpdb; before using this query?
I have a an entity referencing another entity by MappedLongForeignKey.
I am using the CRUDify trait and have a problem.
Entity 1:
id
title (String)
validTo (Date)
Entity 2:
id
...
fk_entity_1 (mapped via MappedLongForeignKey)
In the listings generated by CRUDify for entity 2 I would like to include a column formatted as
fk_entity_1.title ( fk_entity_1.validTo )
I tried to create a function returning such a string and adding that fn to fieldsForDisplay, but it seems fieldsForDisplay requires mapped fields.
Is this possible to accomplish?
* Edit *
What I am trying to accomplish is (using the built in functionality of CRUDify for listings) produce listings as:
{Entity 2 fields} "Entity 1"
... Title_X (2001-01-01)
... Title_Y (2011-02-02)
If worse comes to worst, I can roll my own listings, but I really like the CRUDify functionality.
I'm not quite sure what you're trying to accomplish, but maybe you could override the asHtml method of the fields instead?
I want to include child objects on an IQueryable list..
I want to include a child object on selected columns of some table type IQueryable list..
I tried like this:
IQueryable<Persons> persons = Context.Persons.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName}).AsQueryable();
persons= persons.Include("Address");
this include of child objects is not working..anyone please help...where I am doing wrong..
thanks alot...
Include doesn't work with projection. Moreover it is not needed. Just do this:
var query = context.Persons
.Select(x => new PersonDto
{
Id = x.pkid,
FirstName = x.FirstName,
Address = x.Address
});
Few points here:
No Include
Address accessed directly in projection, EF will handle this
I'm using PersonDto as target of projection. PersonDto has just Id, FirstName and Address.
You can project to custom type or anonymous type but you cannot project to entity type (the mapped type) - it doesn't work and it throws exception.
If you want to use mapped type you can't return only selected scalar columns - all columns will always be loaded. Only navigation properties can be loaded selectively. To overcome this people sometimes use Table splitting but that is something which works if you can divide your big entity into disjunct entities. In your scenario use just projection.
You cannot use Include() on a projection, try this:
Iquerable<Persons> persons = Context.Persons
.Include("Address")
.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName})
.AsQuerable();
Also you have a naming conflict, you project to a type persons and want to hold the results in an IQueryable named persons - one of them is wrong. Is there a reason you need the projection at all? You could just do
Iquerable<Persons> persons = Context.Persons.Include("Address");
First: Check if lazy loading is enabled or not. I experienced different results when it was enabled. I prefer lazy loading being disabled.
Second: Check this syntax:
result = (From person In context.Persons.Include("Address")).ToList();
P.S.: Useful EF Tips & Tricks : http://blogs.msdn.com/b/alexj/archive/2009/03/26/index-of-tips.aspx
UPDATE:
Include is not working, because your are using it on newly created objects, not the objects available in the context. you should use Include before creating new objects.
Check This:
result = (From person In context.Persons.Include("Address") Select New With {.FirstName = item.FirstName, .AddressValue = item.Address.Value}).ToList();