database structure for threads that are editable by many users? - symfony1

at the moment i have a column "user_id" in the "threads" table cause one thread belongs to an user.
i want to make it like Stackoverflow that one thread can be editable by many users and you can see when they edited, what they edited, roll back changes and so on.
im using symfony, is there a plugin for this?
if no, are there any 3rd part libraries/plugins to download for this to integrate to existing database?
cause i have no idea how to implement this. it sounds like mediawiki, something that already exists?
thanks

Using User id as a way of remembering the original creator of the thread. Then just let any user edit a thread, don't limit to only the creator.
To do rollbacks you will need to store versions of your thread. One way would be to have a thread table and a version table.
The thread table would point to the current version, but if you need to rollback you can simply retrieve it from the versions table which should hold the history of all previous versions.

Related

Swift InAppPurchases - give previous customers a free lifetime subscription

So my App was released to the AppStore some months ago and was free to download. I gained like 2k Users. Now I am implementing an auto renewable Subscription model, so future users can use the demo app for free and subscribe to get the full content.
How ever I want to thank my Users "from day one" by giving them free access to all content without paying the subscription.
Is there a "given way" how to implement this because it seems like a common scenario. If not, does someone with IAP experience has a smart workaround how to handle/implement it?
Thanks guys :D
The answer from Paul didnt work for me. Neither did any other solutions.
But i managed to find a solution.
In case you use CoreData as database within your app, you can use the solution i found out for my app.
The idea:
If someone downloads the app from the appstore, he will receive the latest database version in your app.
If someone updates your app, coredata will perform a migration. And this migration updates from bottom to top trough your database versions.
Through this behavior we have the opportunity to dinstinct the two cases.
Solution: We create two new database versions. One will only be updated by the former users. We will set a flag here. The new Users will never get in touch with that.
The first new one will create a new attribut field in any entity (e.g. User) e.g. isFormerUser as a Bool. You can set it per default on true.
Now we create a second new one (the latest one). Trough a Core Data mapper it will take the $source attributes if it migrates.
So by that case, all FormerUser were set on True and will keep that attribute.
Here will the default be False, so if $source didnt exist, set it on false (new Users).
This solution is nice because it gets set once by that migration/update and you dont have to carry hardcoded stuff in your app. Now just create a load/get Function from CoreData for that attribute and set a variable to use in an if-statement.

How to implement a "flag for moderator attention" feature on a Comment model in a Rails app?

I have a Comment model in my app but am encountering a lot of problematic postings that I have to remove manually.
What I want to do is add a "flag for moderator attention" feature so that users of the app have the ability to remove a comment from view without my need to review all content in the app.
I'm thinking that after a comment has been flagged three times, I will remove it from view automatically and then when I have a chance to review these postings I will decide whether to allow them or permanently remove them from view.
What I'm having trouble with is how to implement this.
Should I have a separate table that records all items that have been flagged?
Or should I have a "flag count" field as part of the Comment table that keeps track of how many times a comment has been flagged?
A separate table would allow me to keep track of detailed information about the flagging actions - who is flagging, which IP they are flagging from, etc. This is what I'm leaning towards.
But perhaps a gem or plugin already exists that does this type of thing?
I don't know of any plugin. I like the solution you are leaning towards.
If you want to hide the comment after three flaggings have been created for it, you need to keep track of who created them, so people can flag just once.
I'd create a flag resource (which can hold any kind of flags your users can assign to particular comment), then a flagging resource which connects flags with comments and holds information about the entity which is responsible for flagging (which could be a user or a user represented by IP).
Every comment will then have many flaggings.
You can use state machine to change the status of a comment to "to_be_revised" or something similar after three flaggings have been added. State machine (aasm_state_machine or the one which is now incorporated directly into Rails) will also provide you with named_scopes for groups of comments with the same state.
After revision, you can set the state to "published" again and delete all the flaggings or to "unpublishable" and so hide it forever.
Perhaps the acts-as-flaggable plugin would work.

How do I update only the properties of my models that have changed in MVC?

I'm developing a webapp that allows the editing of records. There is a possibility that two users could be working on the same screen at a time and I want to minimise the damage done, if they both click save.
If User1 requests the page and then makes changes to the Address, Telephone and Contact Details, but before he clicks Save, User2 requests the same page.
User1 then clicks save and the whole model is updated using TryUpdateModel(), if User2 simply appends some detail to the Notes field, when he saves, the TryUpdateModel() method will overwrite the new details User1 saved, with the old details.
I've considered storing the original values for all the model's properties in a hidden form field, and then writing a custom TryUpdateModel to only update the properties that have changed, but this feels a little too like the Viewstate we've all been more than happy to leave behind by moving to MVC.
Is there a pattern for dealing with this problem that I'm not aware of?
How would you handle it?
Update: In answer to the comments below, I'm using Entity Framework.
Anthony
Unless you have any particular requirements for what happens in this case (e.g. lock the record, which of course requires some functionality to undo the lock in the event that the user decides not to make a change) I'd suggest the normal approach is an optimistic lock:
Each update you perform should check that the record hasn't changed in the meantime.
So:
Put an integer "version" property or a guid / rowversion on the record.
Ensure this is contained in a hidden field in the html and is therefore returned with any submit;
When you perform the update, ensure that the (database) record's version/guid/rowversion still matches the value that was in the hidden field [and add 1 to the "version" integer when you do the update if you've decided to go with that manual approach.]
A similar approach is obviously to use a date/time stamp on the record, but don't do that because, to within the accuracy of your system clock, it's flawed.
[I suggest you'll find fuller explanations of the whole approach elsewhere. Certainly if you were to google for information on NHibernate's Version functionality...]
Locking modification of a page while one user is working on it is an option. This is done in some wiki software like dokuwiki. In that case it will usually use some javascript to free the lock after 5-10 minutes of inactivity so others can update it.
Another option might be storing all revisions in a database so when two users submit, both copies are saved and still exist. From there on, all you'd need to do is merge the two.
You usually don't handle this. If two users happen to edit a document at the same time and commit their updates, one of them wins and the other looses.
Resources lockout can be done with stateful desktop applications, but with web applications any lockout scheme you try to implement may only minimize the damage but not prevent it.
Don't try to write an absolutely perfect and secure application. It's already good as it is. Just use it, probably the situation won't come up at all.
If you use LINQ to SQL as your ORM it can handle the issues around changed values using the conflicts collection. However, essentially I'd agree with Mastermind's comment.

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?

Techniques for storing/retrieving historical data in Rails

I'm looking for some ideas about saving a snapshot of some (different) records at the time of an event, for example user getting a document from my application, so that this document can be regenerated later. What strategies do you reccomend? Should I use the same table as the table with current values or use a historical table? Do you know of any plugins that could help me with the task? Please share your thoughts and solutions.
There are several plugins for this.
Acts_audited
acts as audited creates a single table for all of the auditable objects and requires no changes to your existing tables. You get on entry per change with the changes stored as a hash in a memo field, the type of change (CRUD). It is very easy to setup with just a single statement in the application controller specifying which models you want audited.
Rolling back is up to you but the information is there. Because the information stored is just the changes building the whole object may be difficult due to subsequent changes.
Acts_as_versioned
A bit more complicated to setup- you need a separate table for each object you want to version and you have to add a version id to your existing table. Rollback is a very easy. There are forks on github that provide a hash of changes since last version so you can easily highlight the differences (it's what I use). My guess is that this is the most popular solution.
Ones I have no experience with: acts_as_revisable. I'll probably give this one a go next time I need versioning as it looks much more sophisticated.
I did this once awhile back. We created a new table that had a very similar structure to the table we wanted to log and whenever we needed to log something, we did something similar to this:
attr = object_to_log.attributes
# Remove things like created_at, updated_at, other unneeded columns
log = MyLogger.new(attrs)
log.save
There's a very good chance there are plugins/gems to do stuff like this, though.
I have used acts_as_versioned for stuff like this.
The OP is a year old but thought I'd add vestal_versions to the mix. It uses a single table to track serialized hashes of each version. By traversing the record of changes, the models can be reverted to any point in time.
Seems to be the community favorite as of this post...

Resources