Having a bit of a brain dead morning. Messing about with symfony2 and I can't work out how to update a table by a users id. For example: I have a profile table with a user id that is created on registration, so I have an empty table except for a user id. I want to update the the profile table row that belongs to the logged in user. I have a one to one relationship and a getUser method. ?? I am able to get the id of current logged in user, just don't know to update relevant table.
Considering your information I assume User is owner. I don't know if you set the profile on persisting of User...
if (is_null($user->getProfile()) {
$profile = new \Foo\BarBundle\Entity\Profile();
$em->persist($profile);
$user->setProfile($profile);
} else $profile = $user->getProfile();
$profile->setBarBaz('barbaz');
$profile->setFooBaz('foobaz');
$em->flush();
That fine?
Or DQL (I haven't done it this way, may have syntax errors):
$qb = $em->createQueryBuilder();
$result = $qb->update('Foo\BarBundle\Entity\Profile', 'p')
->set('barBaz', 'barbaz')
->set('fooBaz', 'foobaz')
->where('p.user_id = ?1')->setParameter(1, $user->getId())
->getQuery()
->getResult();
Related
Sorry for the abstract title of the question but i will try to explain my intention in details in my question.
I want to create a reminders application in which each user has a separate login in the system but he/she can choose to share an item(in this case a reminder) with another user if he/she chooses. So when that user with whom the item is shared searches in his app he can also see the reminders which are shared with him.
So a user can have a reminder for only himself + a reminder which is shared with him.
This are my data access/retrieval patterns:
So when a user goes inside the application he should be able to see a list of reminders that he created and also the ones which are shared with him
From that list he should be able to search for a reminder by tag(i plan to do that outside dynamodb since the tag would be a set and not a scalar field hence i cannot have an index on that) and also should be able to search for a reminder by title
3.A user should be able to update or delete a reminder
4.A user should be able to create a reminder
5.Also the user should only be able to see future reminders and not the ones in which the expiration date is passed
The table and index creation that i have is created using the below create_table script :
import boto3
def create_reminders_table():
"""Just create the reminders table."""
session = boto3.session.Session(profile_name='dynamo_local')
dynamodb = session.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.create_table(
TableName='Reminders',
KeySchema=[
{
'AttributeName': 'reminder_id',
'KeyType': 'HASH'
}
],
AttributeDefinitions=[
{
'AttributeName': 'reminder_id',
'AttributeType': 'S'
},
{
'AttributeName': 'user_id',
'AttributeType': 'S'
},
{
'AttributeName': 'reminder_title_reminder_id',
'AttributeType': 'S'
}
],
GlobalSecondaryIndexes=[
{
'IndexName': 'UserTitleReminderIdGsi',
'KeySchema': [
{
'AttributeName': 'user_id',
'KeyType': 'HASH'
},
{
'AttributeName': 'reminder_title_reminder_id',
'KeyType': 'RANGE'
}
],
'Projection': {
'ProjectionType': 'INCLUDE',
'NonKeyAttributes': [
'reminder_expiration_date_time'
]
}
}
],
BillingMode='PAY_PER_REQUEST'
)
return table
if __name__ == '__main__':
movie_table = create_reminders_table()
print("Table status:", movie_table.table_status)
So the decision for the global secondary index us to allow a user to search for reminders with a reminder title.
Now to achieve the above case in which a user wants to also share his reminder with someone else i want to do the below change to my table schema . Basically i want to rename the user_id attribute to something like users_id which initially contains the user id of the user who created it but if that reminder is shared with someone then the user_id of the second user is also concatenated with the creator user id and the users_id column is modified .
If i do this i have 2 issues which i can think of:
How do i know the user_id of the user with whom the reminder is shared ? May be now i need to maintain a new table holding user information ? Or can i use some other service like amazon cognito for this?
If i still have the Global Secondary index on the users_id column when i need to search for reminders for a user the query needs to be like : select * from reminders where users_id startswith("Bob")( for example) .
Another option which i can think of(preferred way) is to drop the idea of creating a users_id attribute but instead of keeping the user_id column as is . I would the add the user_id as a sort key (RANGE) key to the table so that the combination of reminder_id and user_id is unique. Then when a user wants to share his created reminder with some other user a new entry is created inside the database with the same reminder_id and a new user id (which is the user id of the user with whom the reminder is shared)
Any help on my dilemma would be greatly appreciated.
Thanks in advance.
You don't mention your query access pattern in any detail, and with DynamoDB your data model flows from the query access pattern. So the below is based only on my imagination of what query patterns you might need. I could be off.
The PK can be the user_id. The SK can be the reminder_id of all reminders the user keeps. That lets you do a Query to get all reminders for a given user. The primary key then is the user id and reminder id in combination, so if you're passing around a reference, use that (not just the reminder_id).
A share gets added by putting another item under the user_id of the person getting shared with. That way a Query for that user can retrieve both their own reminders and those shared with them.
If you need people to list what reminders they've shared and with others, you can put that into the reminder itself as a list of who it's been shared with, if the list is short enough, or instead create a GSI on that share reference (against a shared_by attribute) if the list might be large.
If you need to query for a user's reminders and differentiate their own vs shared, you can prepend the SK with that so SHARED#reminder_id or SELF#reminder_id so a begins_with on the SK can differentiate.
You can refine this in various ways, but I think it would optimize for the "show me my reminders and the reminders shared with me" use cases, while making sharing (or undoing sharing) easy to implement.
I have a datastore entity like this below
Name/ID Parent Rollen email first_name last_name
name=CidassUID Key(Tenant, 'CidassGroupID') ["user","admin"] user#email.com user first name user last name
I would like to make a query w.r.t Name/ID
In GQL I am trying like this
select * from User where Name/ID='CidassUID'
and in python like this..
query = client.query(kind='User')
query.add_filter('Name/ID', '=', 'name=CidassUID')
return list(query.fetch())
Can somebody help how can I get the result via Name/ID?
Thanks a lot
so thats how i solve it in GQL..
select * from User where __key__= Key(Tenant, 'CidassGroupID', User, 'CidassUID')
and for python..
query_key=client.key('Tenant', 'CidassGroupID','User', 'CidassUID')
query.key_filter(query_key,'=')
Hi I am new to laravel but I would like to load all the bookings for the currently logged in user.
I have tried doing this
//check if user is logged in
if ($user = Auth::user()) {
//get only the bookings for the currently logged in user
$allProducts =Booking::where('client', Auth::user()->name)->where('name', $name)->first();
//store the bookings in a products variable
$products = json_decode(json_encode($allProducts));
//Loop through the products:
foreach ($products as $key => $val) {
//get the name of the service by matching it's id in the service model to the service column in the products
$service_name = Service::where(['id' => $val->service])->first();
//get the charge amount of the service by matching it's id in the Charge model to the charge column in the products
$service_fee = Charge::where(['id' => $val->charge])->first();
//get the status of the service by matching it's id in the status model to the status column in the products
$service_status = Status::where(['id' => $val->status])->first();
$products[$key]->service_name = $service_name->name;
$products[$key]->service_fee = $service_fee->total;
$products[$key]->service_status = $service_status->name;
}
return view('client.booking.view_bookings')->with(compact('products'));
}
return view('/login');
}
But that is giving me an error: Undefined variable: name on the line
$allProducts =Booking::where('client', Auth::user()->name)->where('name', $name)->first();
What could I be doing wrong? and how can I solve it to dsplay only the required data
I have tried to understand what you are doing without success but from your explanations in the comments, I think I know what you want to do.
Since you said that this code works well for you except that it gives you the results of all the data in the database irrespective of the logged in user
$allProducts = Booking::get();
it is because that creates a query that selects all the data in the database.
Whatv you need is to add a where clause to your statement. to do that simply add this to the above line of code
where('client', Auth::user()->name)
it will return only the data that that contains the client column equal to the name of the currently logged in user.
Therefore the entire line of code becomes;
$allProducts = Booking::get()->where('client', Auth::user()->name);
Alternatively you could use filters
I am working in a Symfony 1.4 project with Propel 1.4.2.
I have 2 related tables. workshop and trainers which is a many to many relation mapped by a join table (workshop_trainers) which contains the workshop_id and the trainer_id).
In my Workshop Form I have a select box for adding the trainers to the workshop. The problem is when the workshop is new (Create) I get an error:
Cannot add or update a child row: a foreign key constraint fails
This happens because, when saving the workshop_trainers relation the workshop_id field is null. IsnĀ“t Propel intelligent enough to know that there is a relation between the tables and save the base object first? What I am doing wrong?
My trainer list widget.
$this->widgetSchema['workshop_trainer_list'] = new sfWidgetFormChoice(array(
'choices' => $trainers,
'multiple' => true,
));
Thanks for your help.
This is not fixing the problem but that's the easiest practical solution to this problem:
In the form, simply deactivate the workshop_trainer_list field if the object is a new one (doesn't have an ID yet).
Something like:
if ($this->getObject()->isNew())
{
$this->offsetUnset('workshop_trainer_list'); // not sure of that method name
}
A better solution is to update the doSave method to have the ID first, something like this:
protected function doSave($con = null)
{
$isNew = $this->getObject()->isNew();
if (null === $con)
{
$con = $this->getConnection();
}
// retrieve the value of workshop_trainer_list here and remove it from the form
$trainers = ...
$this->offsetUnset('workshop_trainer_list');
// save without it
parent::doSave($con);
// add it back
$this->getObject()->set...
// save
$this->getObject()->save($con);
}
Sometimes in Salesforce tests you need to create User objects to run part of the test as a speciifc type of user.
However since the Salesforce Summer 08 update, attempts to create both User objects and normal objects (such as Accounts) in the same test lead to the following error:
MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account
Note that the error doesn't happen when you run the tests from Eclipse/Force.com IDE, but it does happen when you deploy to Salesforce and then run the tests from within Salesforce.
How do I re-write my tests to avoid this error?
Here's a simple example of a test that causes the error:
static testMethod void test_mixed_dmlbug() {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
User u = new User(alias = 'standt', email='standarduser#testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser#testorg.com');
Account a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
System.runAs(u) {
a.PersonEmail = 'test#madeupaddress.com';
update a;
}
}
Not many Salesforce people on here yet, I guess.
I found a solution, I don't know why it works, but it works.
All parts of the test that access normal objects need to be wrapped in a System.runAs that explicitly uses the current user, like this:
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
So, the example text_mixed_dmlbug method given in the question, would become:
static testMethod void test_mixed_dmlbug() {
User u;
Account a;
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
u = new User(alias = 'standt', email='standarduser#testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser#testorg.com');
a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
}
System.runAs(u) {
a.PersonEmail = 'test#madeupaddress.com';
update a;
}
}
Then the MIXED_DML_OPERATION errors stop happening.
It seems like you've found a workaround. I just wanted to try and clear up why you where getting this error.
I think you are running into this issue (per http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):
sObjects That Cannot Be Used Together in DML Operations
Some sObjects require that you perform DML operations on only one type per transaction. For example, you cannot insert an account, then insert a user or a group member in a single transaction. The following sObjects cannot be used together in a transaction:
* Group1
* GroupMember
* QueueSObject
* User2
* UserRole
* UserTerritory
* Territory
Important The primary exception to
this is when you are using the runAs
method in a test.
In addition, the Summer 08 Release notes (that link is a PDF) say:
In previous releases, in a single
transaction that involved triggers,
you could perform DML operations on
more than one type of sObject, for
example, you could insert an account,
then insert a user. As of Summer
'08, you can only perform DML
operations on a single type of sObject
from the following list of sObjects.
For example, you cannot insert an
account, then insert a user, or update
a group, then insert a group
member.
Group
GroupMember
QueueSObject
User
UserRole
UserTerritory
Territory
In addition, User and Territory now
support the insert and update DML
operations, and UserRole
now supports the insert, update delete
and upsert DML operations.
Apex DML operations are not supported
on the following sObjects:
AccountTerritoryAssignmentRule
AccountTerritoryAssignmentRuleItem
UserAccountTeamMember
This behavior is actually documented in the salesforce documentation: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dml_non_mix_sobjects.htm?SearchType. Read where it say "Important
The primary exception to this is when you are using the runAs method in a test"
Just found this in the documentation:
Other Uses of runAs
You can also use the runAs method to perform mixed DML operations in your test by enclosing the DML operations within the runAs block. In this way, you bypass the mixed DML error that is otherwise returned when inserting or updating setup objects together with other sObjects. See sObjects That Cannot Be Used Together in DML Operations.
So it looks like the RunAs workaround is not a workaround but is assumed by Salesforce as the only way of going by the mixed DML issue.
Hope this helps
Reference
This error is so common when attempting to create user and other objects records in a single transaction in apex.
Workaround in apex class/trigger : use future method for creating user when encountered the error
Workaround in test class : don't try creating a new user data, instead use ))>
code-snippet at -
https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html