convert existing record to new record automatically - ruby-on-rails

I am wondering if, in some hidden corner of the API I haven't yet run into, if there is a way to clone an existing record into a new one, so when saved it will have a new id assigned?
This is intended to be used on an event site I am writing, which will allow people to import from previous years, but copying it will allow updating the event description with new content.

You can use dup method for this.
Given object user1 of model User, you can do:
user2 = user1.dup
user2.save
Doing user2 = user1.dup clones user1 into user2, and user2 has no id, created_at and updated_at values assigned and it is treated as a new record.

Related

In a PostgreSQL/Rails app, what decides how the 'id' field is allocated when 'create' method is called?

I have a model called "Post". Because of reasons, I had to create Posts with specific id values. When I run Post.last, it gives me the Post with the highest id value. However, when I run Post.create(), it tries to create a Post with an id greater by 1 than the id of the last Post created without a specified id.
The number of Posts in my database created without a specified id has now caught up to the id of the first Post whose id I specified. This results in an error, because the Post that Rails tries to create would have an id value that's already taken.
Is it possible to somehow override id allocation, to make it go by the value of Post.last.id?
The IDs are generated by a Postgres sequence. Rails will have generated this for you as part of a rails generate model Post, and if you went with all the defaults, your table is called posts and the sequence should be called posts_id_seq.
You need to reset the sequence to the next value after the ID you've already used.
If the next value you want to use is, for example, 5000, something like
ALTER SEQUENCE posts_id_seq RESTART WITH 5000;

Unable to detect a Delete on the server from the client

In my database, I have three entities: User, List and UserList (represents a many to many relationship between user and List). In my app, I have initialized SyncContext with StoreTrackingOptions.NotifyLocalAndServerOperations tracking option.
await Client.SyncContext.InitializeAsync(_store, StoreTrackingOptions.NotifyLocalAndServerOperations);
When my app is running for a given User, when I add a new List association for that user (by inserting a linkage record into UserList), I am able to detect this change:
var subscription = Client.EventManager.Subscribe<StoreOperationCompletedEvent>(async (storeEvent) => await StoreChangedEventHandler(storeEvent));
protected async Task StoreChangedEventHandler(StoreOperationCompletedEvent storeEvent) {..}
Now note that creating the linkage, will pull the UserList record for the User as well as the List record referenced by UserList.
When I delete this linkage record though, there is no notification of that coming to my client.
Questions: Is such notification (of deleted records) possible? If so, how do I make it happen?
I have solved this issue by enabling soft delete on the server (Azure Mobile Server SDK). By doing that, all soft-deleted records are pulled back to the client and I can filter them out for presentation. Works for me but may not work for everyone else.

CloudKit - How to Save Record If Not Exists

I am trying to make a Record Type that contains unique values, and would act as the target reference objects to another Record Type. For example, Record Type - Movies would contain unique list of movies submitted by users. And FavoriteMovies would contain a Users reference and a Movies reference. Users could select from a list of existing Movies, or add new ones to it.
The problem happens if I create a new Movies record, while another user creates a new record with the same name (after I retrieved the list of movies, but before I attempt to add a new one). The two new records are considered different records with different recordIDs. This means that once I saved the new one, there will be two instances of Movies with the save name.
I'm not able to find a way to perform a Save If Not Exists type operation to the Movies Record Type. I could do a save in the completionBlock of a query, but those two actions would not be an atomic transaction to guarantee uniqueness. As far as I know this is also the case with chaining CKQueryOperation with CKModifyRecordsOperation.
Is there a way to insert a record only if the value does not exists in a single transaction?
If I understood correctly your use case, you can make movieRecord.recordID.recordName the movie's name and use CKModifyRecordsOperation with savePolicy IfServerRecordUnchanged to effectively Save If Not Exists. It would then return an error that you can ignore if you try to save a record that already exists on the server:
let saveRecordsOperation = CKModifyRecordsOperation()
saveRecordsOperation.recordsToSave = [movieRecord]
saveRecordsOperation.savePolicy = .IfServerRecordUnchanged
With the savePolicy IfServerRecordUnchanged this operation will save a new Movie record if it doesn't exist yet on the server (Save If Not Exists) but will return the error below on any subsequent try to overwrite a Movie record that already exists on the server (provided it is not a newer modified version of a record that was fetched from the server):
<CKError 0x14d23980: "Server Record Changed" (14/2017); server message = "record to insert already exists">
You could deal with this conflict in the perRecordCompletionBlock but in your specific use case you can just do nothing about the conflict error so each Movie record will be the first saved record with that CKRecordID.

Dynamics CRM Merge Two Contacts with C# code, modified example from SDK

I've been trying to get the Merge example in Dynamics CRM 2011 SDK to work.
http://msdn.microsoft.com/en-us/library/hh547408.aspx
I've modified it a bit. I've created two Contacts instead of Accounts (although some variable names in the code might suggest otherwise. For example _account1Id is in fact a GUID for contact1.)
The first Contact record has name, surname and telephone fields filled.
The second Contact record has name, surname and email fields filled.
The part where merge occurs is below. The original code can bee seen from the link at the top.
When I run the example with following modifications, the e-mail address doesn't get merged into the new contact record. What I get is one merged Contact with the values from one of the records, with address data added, but no e-mail. I thought this was supposed to fill empty fields of the primary record with the non-empty fields from the second record.
Being very new to Ms Dynamics CRM, I couldn't understand the reason after much googling and debugging. I'll be glad if someone can give me some feedback about what the problem might be.
Thanks in advance.
_serviceProxy.EnableProxyTypes();
CreateRequiredRecords(); // created two contacts with same name, surname. first record has telephone1 filled, second record has emailaddress filled.
EntityReference target = new EntityReference();
target.Id = _account1Id;
target.LogicalName = Contact.EntityLogicalName;
MergeRequest merge = new MergeRequest();
merge.SubordinateId = _account2Id;
merge.Target = target;
merge.PerformParentingChecks = false;
Contact updateContent = new Contact();
updateContent.Address1_Line1 = "test";
merge.UpdateContent = updateContent;
MergeResponse merged = (MergeResponse)_serviceProxy.Execute(merge);
Contact mergeeAccount =
(Contact)_serviceProxy.Retrieve(Contact.EntityLogicalName,
_account2Id, new ColumnSet(allColumns: true));
if (mergeeAccount.Merged == true)
{
Contact mergedAccount =
(Contact)_serviceProxy.Retrieve(Contact.EntityLogicalName,
_account1Id, new ColumnSet(allColumns: true));
}
That behaviour would be as expected - the Merge will move over child records for you from the subordinate to the master (so potentially opportunities, addresses etc.) but not try to workout which fields you want copied over. The reasoning (I would guess) is the potential business logic implications are endless - do you want to copy over emails? what if all email fields are filled? what about custom fields? And lots of other cases I'm sure everyone can think of.
Edited:
To workaround this, there is a property on the MergeRequest class called UpdateContent. If you update fields on this property, the values will be merged into the parent record.
You can actually see this in the link you has posted:
// Create another account to hold new data to merge into the entity.
// If you use the subordinate account object, its data will be merged.
Account updateContent = new Account();
updateContent.Address1_Line1 = "test";

inserting data in many to many relationship in entity framework

I have two tables (users , messages) which there is many to many relationship for them.
i want to add new messages in message table and allocate massages to current users.
Also i insert data like below:
Message newMessage = Message.CreateMessage("MessageText", "DateTime");
newMessage.Users.Add(new User{..... });
context.SaveChange();
this code will execute a query which add a new user in users table while the users table has some specified users and i don't want to add new user but as i mentioned i want to add new messages in message table and allocate massages to current users.
how should i do that?
The problem is you are creating a new User object with an existing primary key. When SaveChanges() is called EF detects the changes of the entities its already tracking and new entities added. Since your new User object was not tracked by EF, it tries to insert it.
You need to explicitly tell EF that the created user is an existing one. To do that you need to attach it.
Message newMessage = Message.CreateMessage("MessageText", "DateTime");
var user = new User{ Id = "foo" };
context.Users.Attach(user);
newMessage.Users.Add(user);
context.SaveChange();

Resources