how to edit and commit a domain with its hasmany domain - grails

I'm currently have the task to move our java-application code to a web-application.
I would decide to use grails for this task. (I developed already a few simple applications in grails and they worked nicely.)
But with one behaviour, I have my serious problems.
Giving a domain model with:
a customer has many addresses
an address belongs to customer and has many contacts
a contact belongs to address
edit: Because I use the "belongsTo" setting, the cascading save would not be a problem (I think).
What I would need:
While creating a customer I need the possibility to attach a few addresses and there I should have the possibility to add a few contacts.
But all should be committed to the database after pressing the save button in the customer view. (The same with editing a customer...)
Current behaviour:
With the default controllers and views, I first need to commit the customer and could than add the addresses the same with the contacts (first commit the address and than add the contacts).
edit:
(as I understand correctly) the data binding is used by default in the "generate-controller" and "generate-view" resulting classes.
The thing where I have no idea is, how to handle the web-page-flow, that I could add an address and there a few contacts, without saving the customer domain before. And after switching several times between the views "customer.create", "address.create" and "contact.create" having the whole structure still present.
(I tried to save the customer-domain in the session-object and in the create.address view save-method, I fetched the customer from the session and added the addressInstance to the address-list of the customer, saved the customer again in the session and switched back to a new editSession-action for the customerInstance which fetches the instance to be edited from the session. But it seemed to me, that only the customerInstance is contained in the session and not the associated objects... [omg, hope I could make me understand...])
Would my needed workflow somehow be possible? (Hopefully you could point me to some documentation or examples, please)
Thanks in advance,
Susanne.

There are many possibilities, here are a few suggestions that may help you find a solution:
The user friendliest design is to create all three objects on the same page (Why would a user want to switch between three screens to setup a new Customer?). This takes a bit more work on the page but you can create/edit and save the customer in one go.
If you have separate screens to add Customer, Address & Contact let the user start with creating the customer. save it. When the user adds an Address pass along the Customer id. save it linked to the Customer (you have the id). Same for Contacts.
If you don't want the user to explicitly save the Customer before he can add an Address you can save the Customer automatically when the user clicks "add address" on the Customer page. Same for Contacts.
If you don't want to show the unfinished customer to someone else you can add an in creation flag on the customer to filter unfinished Customers (or you use another table to link to unfinished users, if you dislike the 'state' information on the customer). When the user finally decides the Customer is ready (pressing save on the Customer page) you clear the unfinished state (or remove it from the unfinished table) to make the new Customer visible to all users.
Doing it like this you could even recover from session timeouts and offer the user to continue creation of the customer.

Related

Organizing and grouping sophisticated processes in rails

As an example, lets say I have 4 models: Product, Order, Customer, Store
When an order is placed by a customer in a store, the store's owner would get an email asking to confirm the UPC code on the product. Once confirmed, the customer would get an email with a code that when they enter it into their portal, it activates the product.
There is a lot of logic here, which spans several models. For example, when the order is completed, it creates a new inactive product with a confirmation key. The store owner accesses this product by its confirmation key and adds the upc information to it. Only then, once the product has upc information can the customer confirm it.
TL;DR - My question is, what is the best way to group a large process, which involves many models, into a central location? Instead of accessing several other models from within one model, it would make more sense to have it centralized. Is there a best-practice for this type of logic?
This case is typically going to result in a "Service Object" that would be placed in /lib.
This allows for testing the workflow in isolation and doesn't fatten up models unnecessarily.
You can find a good intro to Service Objects here:
https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services
http://multithreaded.stitchfix.com/blog/2015/06/02/anatomy-of-service-objects-in-rails/

How to dynamically populate Jira custom fields?

I'm new to the Jira admin side of things after having used it in a previous company as an end-user for several years. We are using the standard Jira workflow. The scenario I'm struggling with is the following. I'm attempting to match some of the functionality of our old-proprietary issue database. Right now I'm using many of the standard Jira fields, with only two new custom fields (both single Select Lists populated manually by me):
1) Customer = customer name who sent the new issue email to our support team
2) Customer Contact = the main customer contact, currently populated by the custom list
I created these two custom fields because we have external customers who call or email issues they have using our hosted software. Currently our system creates a simple new issue when a customer sends an email to our support email account. Our support team then goes in and cleans up the data and makes sure that all the required Jira fields have data, the comments are good, reproducible steps, etc. (Currently we do not strip out the customer domain name to auto-populate the Customer custom field, but I might try doing that soon.)
Our support team is asking that I add the following two new customer fields:
3) Customer phone number
4) Customer connection / login info
What I would like to implement is a system that goes something like this:
Customer name gets inputted (either automatically by grabbing domain name of customer email address or manually by our support team) into the Customer custom field. Customer name selected should be "pushed" into the Customer Contact Select List to help sub-select values for that particular customer.
The Customer Contact Select list should be "smart" or dynamic in that some pre-processing is done where the Customer name is grabbed so that it doesn't show ALL customers contacts for the tech support person to select, it just shows them the customer contacts for the customer that was selected.
Along with the filtered customer contacts, I would want to only see the Customer phone number for the contact that was populated in the Customer Contact select list.
And finally I would want to see the Customer connection information for the particular Customer that was selected.I've done this type of smart combo boxes in the past when I created Java / Database applications, so I have a feeling that this is possible in Jira. I'm just looking for the easiest way to implement this. It seems like there might be some external plugins that might help do this (ex. the values for the Custom fields are stored in a database table so they can be queried and the proper filtered result sets can be populated into the select lists.), or maybe using post functions (update issue), etc. But before I spent more effort investigating, I know this sort of thing has to be somewhere common and wanted to ask the Jira admin experts what the best practice would be for this type of functionality in custom fields. Please share your experience with how to solve this type of scenario. Thanks in advance!
Here is the way that tells how to import multiple options at once. Probably that would help u.
https://answers.atlassian.com/questions/92385/importing-project-from-another-jira-instance-how-do-we-mass-import-custom-field-multi-select-options?page=1#92622
EDIT
and here is the complete code to update another select list using new select list.
How to add new values to select list field in jira dynamically or using plug-in

Fixing duplicate records in a rails app from an autocomplete form

I'm building a Rails 3.1 application that allows people to submit events. One of the fields for the event is a venue. On the create/edit form, the venue_name field has autocomplete functionality so it displays venues with a similar name, but the user is able to enter any name.
When the form is submitted, I'm using find_or_create_by_name when attaching the venue to the event model.
I'm doing this because it's not possible for us to maintain a complete list of venues and I don't want to prevent people from submitting an event because the venue isn't in the list.
The problem is that it's quite likely we'll get duplicates over time like "Venue Name" and "The Venue Name" or any number of other possibilities.
I was thinking that I probably just need to create an administrative tool that allows the admin to review recent venues and if he/she thinks they're duplicates to search/select a master record and have the duplicate record's association copied over to the master record and once successful to delete the duplicate record.
Is this a good approach? In terms of the data manipulation would it be best to handle this in a transaction? Would it be best to add this functionality in a sort of utility class - or directly in the Venue model?
Thanks for your time.
If I were going to put together a system like that, I'd probably try to find a unique identifier I could associate with each venue - perhaps an address or a phone number?
So, if I had "The Clubhouse" with a phone number 503-555-1212, and someone tried to input a new venue called "Clubhouse" with the phone number 503-555-1212, I might take them to an interstitial page where I ask them "Did you mean this location?"
Barring that, I might ask for a phone number or address first, then present a list of possible matches with the option to create a new venue.
Otherwise, you're introducing a lot of potential for error at the admin level, plus you run into a scalability problem. If your admin has to review 10 entries a month, maybe not so bad - but if your app takes off and that number goes to 1000, that becomes unmanageable fast!

Giving a user a 'primary key' inside their data domain

I have a rails app that consists of lots of accounts.
Inside these accounts users can create tickets.
What is the best way to give each ticket a Id that is sequential inside their account?
Obviously managing the id's myself seems to be the initial answer, but this seems to be filled with all sort of edge cases that would cause issues (for instance, two tickets writing down to the DB at once...)
I think you'll end up managing them yourself - I've implemented something similar previously, account stored 'current_ticket_id' and then when a ticket (for example) get's created it is still stored with a global PK but then an observer assigns it a friendly_ticket_id and then increments to one on the account model for the next time round. You can use the friendly_ticket_id scoped to the account via your URLs to make sure you get the right ticket back.

Allow users to remove their account

I am developing a gallery which allows users to post photos, comments, vote and do many other tasks.
Now I think that it is correct to allow users to unsubscribe and remove all their data if they want to. However it is difficult to allow such a thing because you run the risk to break your application (e.g. what should I do when a comment has many replies? what should I do with pages that have many revisions by different users?).
Photos can be easily removed, but for other data (i.e. comments, revisions...) I thought that there are three possibilities:
assign it to the admin
assign it to a user called "removed-user"
mantain the current associations (i.e. the user ID) and only rename user's data (e.g. assign a new username such as "removed-user-24" and a non-existent e-mail such as "noreply-removed-user-24#mysite.com"
What are the best practices to follow when we allow users to remove their accounts? How do you implement them (particularly in Rails)?
I've typically solved this type of problem by having an active flag on user, and simply setting active to false when the user is deleted. That way I maintain referential integrity throughout the system even if a user is "deleted". In the business layer I always validate a user is active before allowing them to perform operations. I also filter inactive users when retrieving data.
The usual thing to do is instead of deleting them from a database, add a boolean flag field and have it be true for valid users and false for invalid users. You will have to add code to filter on the flag. You should also remove all relevant data from the user that you can. The primary purpose of this flag is to keep the links intact. It is a variant of the renaming the user's data, but the flag will be easier to check.
Ideally in a system you would not want to "hard delete" data. The best way I know of and that we have implemented in past is "soft delete". Maintain a status column in all your data tables which ideally refers to the fact whether the row is active or not. Any row when created is "Active" by default; however as entries are deleted; they are made inactive.
All select queries which display data on screen filter results for only "active records". This way you get following advantages:
1. Data Recovery is possible.
2. You can have a scheduled task on database level, which can take care of hard deletes of once in a way; if really needed. (Like a SQL procedure or something)
3. You can have an admin screen to be able to decide which accounts, entries etc you'd really want to mark for deletion
4. A temperory disabling of account can also be implemented with same solution.
In prod environments where I have worked on, a hard delete is a strict No-No. Infact audits are maintained for deletes also. But if application is really small; it'd be upto user.
I would still suggest a "virtual delete" or a "soft delete" with periodic cleanup on db level; which will be faster efficient and optimized way of cleaning up.
I generally don't like to delete anything and instead opt to mark records as deleted/unpublished using states (with AASM i.e. acts as state machine).
I prefer states and events to just using flags as you can use events to update attributes and send emails etc. in one foul swoop. Then check states to decide what to do later on.
HTH.
I would recommend putting in a delete date field that contains the date/time the user unsubscribed - not only to the user record, but to all information related to that user. The app should check the field prior to displaying anything. You can then run a hard delete for all records 30 days (your choice of time) after the delete date. This will allow the information not to be shown (you will probably need to update the app in a few places), time to allow the user to re-subscribe (accidental or rethinking) and a scheduled process to delete old data. I would remove ALL information about the member and any related comments about the member or their prior published data (photos, etc.)
I am sure it changing lot since update with Data Protection and GDPR, etc.
the reason I found this page as I was looking for advice because of new Apply policy on account deletion requirements extended https://developer.apple.com/news/?id=i71db0mv
We are using Ruby on Rails right now. Your answers seem a little outdated? or not or still useful right now
I was thinking something like that
create a new table “old_user_table” with old user_id , First name, Second name, email, and booking slug.
It will allow keep all users who did previous booking. And deleted their user ID in the app. We need to keep all records for booking for audit purpose in the last 5 years in the app.
the user setup with this app, the user but never booking, then the user will not transfer to “old_user_table” cos the user never booking.
Does it make sense? something like that?

Resources