I have a Rails website with three tables: User, Task, and TaskInstance. The Task table is like a master list of tasks, not coupled to any particular user, whereas the TaskInstance table contains records that indicate a user's completion of a particular task. In other words, a TaskInstance has a User id, a Task id, and a completion status (boolean). A User has many TaskInstances.
I'd like to allow administrators to add new Tasks. Doing so should create a new TaskInstance for that Task for every User. However, that doesn't sound like it would scale well. Say I have fifty thousand Users, creation of a new Task would require fifty thousand TaskInstances to be created immediately on the spot.
It would be good if some sort of lazy loading could be done instead, but I don't know where I would do it. I could do it at login e.g. when a User logs in, check if a new Task has been created; if so, create a new TaskInstance only for that particular User. But then what about users that are already logged in when the new Task is created?
I guess I'm just wondering what the preferred approach to this sort of problem is.
Move this to the community wiki if you need to.
Don't create the TaskInstances right upfront, but only when they are needed. Since a new Task gets created anyway, it can be displayed to any User, no matter if there is a TaskInstance or not. As soon as a user decides to start with a Task, the TaskInstance should get instantiated.
Related
I've read into Cancan and Pundit (also Devise) for managing users in a Rails App. But I wanted to know if something was possible.
Basically, I want to have users change/add lines in a table (using SQLite at the moment, but will be moving to SQL in the future - call them entries). But before it gets added to the actual table, it gets sent to the admin for approval. Then the admin can just hit 'approve' and the statement gets run.
I'm just confused about how to hold the statement and then when approved, the statement runs. Any information would be appreciated.
By statement, do you mean that your users are actually writing the SQL themselves?
If not, I'd setup a second model identical to your first that acts like a queue of some sort that holds the proposed changes/additions. This way, you'll be able to compare the old and new statements if necessary, and, when approved, you'll be able to perform the create/update magic on your original model.
Hope this gives you some ideas!
Perhaps it is my lack of experience still with really stretching MVC and Entity Framework but I've run into a problem I can't really figure out.
Up until now my applications have been simple: I show and hide a few divs in a View, and when the user has entered all data they hit submit and I save it to the database using EF. The complication I have now is I have basically have to have a flow where:
Person Registers -> Register Another Person? If Yes -> Person Registers -> And So On...
EDIT* To Clarify: Person comes in to Register a group of people. The first screen is a form where they enter identification info, next is clicked, and then They are asked if they'd like to add someone else, if they click yes they repeat that process. I create a Registration Object each time this happens until they don't want to add anymore, after which they are directed to a "Confirmation" action that shows them their registrations and let's them submit their registrations.
I need to have a way to temporarily hold that data while the user jumps to different actions and ultimately submits it to be saved. I'd prefer not to hold a bunch of models in a Session variable.
Well, in your given example, you shouldn't be holding on to anything. After each person is registered, that data can be saved to the database immediately before redirecting back to the form to allow the user to register another person. At each step, you're dealing with a discrete unit, so there's no reason not to just save it immediately.
In a different scenario, perhaps something like a wizard, where you collect partial info in multiple steps, which culminate to produce one discrete unit, your only real option is to use something like TempData. TempData is still session-based, and uses the Session object under the hood, but it does have the advantage over traditional use of Session that the data is only persisted through the next request, whereas Session data is persisted for the life of the session, which can be anywhere from minutes to weeks based on configuration.
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.
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?
I have a MOSS2007 web application (created using publishing site template). In this app, user is allowed to add various items of interest. Those item of interest are saved in DB as a group. Thus each user has more than one group of interests. User is allowed to add/delete/edit interests within a group at will.
My queries are as follows
How to handle cases when user adds items of interest and never saves it in a group before MOSS2007 session times out?
How to handle cases when user adds items of interest, saves it and then adds more before MOSS2007 session times out.
How to handle cases when user adds items of interest, saves it, delete some items from saved ones before MOSS2007 session times out.
I'd suggest:
How to handle cases when user adds
items of interest and never saves it
in a group before MOSS2007 session
times out?
Items are either stored in a local cookie, so they are there when the user logs in to MOSS again, or are lost.
How to handle cases when user adds
items of interest, saves it and then
adds more before MOSS2007 session
times out.
New items are either saved in cookie, or lost.
How to handle cases when user adds
items of interest, saves it, delete
some items from saved ones before
MOSS2007 session times out.
The deletion method should delete the records from the database. So they would be synced already. If however, you need a rollback option, you could do something similar to the Recycle bin functionality in MOSS...
Hope that helps.