How can I increment a value in a column table using ORM in php

I know using a RDBMS, I can do something like this, UPDATE tableName SET vote_up = vote_up + 1 WHERE user = $user.
How, then can I translate this to ORM?

NB. Am not using any ORM software like doctrine but doing it the way I read it in php novice to Ninja 6th edition coauthored by @kevinyank and @TomB

I think it would just be a case of adding for it a method to your table class.
Maybe something like:-

public function increment($column, $amount){...}

I’ll let you work out the rest. :wink:

If you are using an ORM you should not be making changes to individual database columns like that. Philosophically you want to treat each record as its own distinct entity and deal with the object, not directly interact with the underlying data.

Building on the code from the book you would fetch the record and save it back:

$userVote = $votesTable->find('user', $userId);
$userVote->vote_up += 1;
$votesTable->save($userVote);

This is less efficient for the CPU but gives you better flexibility as a developer. There’s nothing here that suggests the data is being stored in a database. You could swap out $votesTable with a variant that saved as JSON or XML, or connected to a third party API.

Related article: https://r.je/4-reasons-to-avoid-foreign-key-constraints-database-logic.html

1 Like

Thinking about it, I neglected to have anything to specify which row here.

Note that while this will work perfectly fine for low traffic websites, it will suffer from concurrency issues on busier websites.

Example:

User A:
fetch number of views: 10
add one: 11
write to database: 11

At the exact same time, user B also does this, before user A had a chance to write 11 to the database:
fetch number of views: 10
add one: 11
write to database: 11

So the number of views in the database is now 11, even though it should have been 12

If you want to avoid these you’d need to work around the ORM and do a manual query like your wrote in your post

2 Likes

Yes you’re right, really an incremental field like that would be better expressed with it’s own table anyway: INSERT INTO votes (userId, rating) VALUES ($user, -1); where rating is +1 or -1 for upvote/downvote assuming that’s what this table represents.

1 Like

I have to go with this(if this is the best way to do it). This means that I have to do it inside the controller? Or better still to separate sql query from controller into its own file?

Can you give me a more explanation on this.

I got this error when I did it this way

Warning: Attempt to assign property of non-object in /home/vagrant/Code/Project/classes/Ndb/Controllers/Vote.php on line 47

And this is line 47
$vote->voteUp += 1;

My code was only really indicitive. You probably need $userVote[0]->vote_up. Your examples also contain both voteUp and vote_up. The property will need to exactly match the column name.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.