Ruby: Model ActiveRecord::Relation#touch_all

This commit is contained in:
Harry Maclean
2022-06-17 10:19:53 +12:00
parent 7dfab371f6
commit 20ff4c4299
3 changed files with 28 additions and 1 deletions

View File

@@ -359,7 +359,7 @@ private module Persistence {
}
/**
* Holds if `call` has a keyword argument of with value `value`.
* Holds if `call` has a keyword argument with value `value`.
*/
private predicate keywordArgumentWithValue(DataFlow::CallNode call, DataFlow::ExprNode value) {
exists(ExprNodes::PairCfgNode pair | pair = call.getArgument(_).asExpr() |
@@ -412,6 +412,28 @@ private module Persistence {
}
}
/**
* A call to `ActiveRecord::Relation#touch_all`, which updates the `updated_at`
* attribute on all records in the relation, setting it to the current time or
* the time specified. If passed additional attribute names, they will also be
* updated with the time.
* Examples:
* ```rb
* Person.all.touch_all
* Person.where(name: "David").touch_all
* Person.all.touch_all(:created_at)
* Person.all.touch_all(time: Time.new(2020, 5, 16, 0, 0, 0))
* ```
*/
private class TouchAllCall extends DataFlow::CallNode, PersistentWriteAccess::Range {
TouchAllCall() {
exists(this.asExpr().getExpr().(ActiveRecordModelClassMethodCall).getReceiverClass()) and
this.getMethodName() = "touch_all"
}
override DataFlow::Node getValue() { result = this.getKeywordArgument("time") }
}
/** A call to e.g. `User.insert_all([{name: "foo"}, {name: "bar"}])` */
private class InsertAllLikeCall extends DataFlow::CallNode, PersistentWriteAccess::Range {
private ExprNodes::ArrayLiteralCfgNode arr;

View File

@@ -14,6 +14,7 @@
| app/controllers/users_controller.rb:20:7:20:57 | call to update_attributes | app/controllers/users_controller.rb:20:49:20:55 | call to get_uid |
| app/controllers/users_controller.rb:23:7:23:42 | call to update_attribute | app/controllers/users_controller.rb:23:37:23:41 | "U13" |
| app/controllers/users_controller.rb:26:19:26:23 | ... = ... | app/controllers/users_controller.rb:26:19:26:23 | "U14" |
| app/controllers/users_controller.rb:31:7:31:32 | call to touch_all | app/controllers/users_controller.rb:31:28:31:31 | call to time |
| app/models/user.rb:4:5:4:28 | call to update | app/models/user.rb:4:23:4:27 | "U15" |
| app/models/user.rb:5:5:5:23 | call to update | app/models/user.rb:5:18:5:22 | "U16" |
| app/models/user.rb:6:5:6:56 | call to update_attributes | app/models/user.rb:6:35:6:39 | "U17" |

View File

@@ -25,6 +25,10 @@ module Users
# AssignAttributeCall
user.name = "U14"
user.save
# TouchAllCall
User.touch_all
User.touch_all(time: time)
end
def get_uid