rspec/rules/S5497/apex/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

80 lines
2.3 KiB
Plaintext

== Why is this an issue?
DML statements should not be executed in class constructors, https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_static.htm[instance initialization code blocks or static initialization code blocks] for two reasons:
* It is counter intuitive. Developers will not expect the instantiation of an object to modify records.
* Constructor and/or initialization code blocks of VisualForce controllers will fail if they try to execute DML statements. This is also true for indirect calls to DML statements: they can't instantiate objects which execute DML statements in their own constructors/initialization code. Having to check if a constructor can or cannot be called makes development more complex.
This rule raises an issue when a class constructor, an instance initialization block or a static initialization block executes a DML statement.
=== Noncompliant code example
[source,apex]
----
public class MyController {
{
List<Task> tasks = [Select Id, Subject FROM Task];
for (Task t : tasks) {
t.subject = 'instance initialization code block';
}
update tasks; // Noncompliant
}
static {
List<Task> tasks = [Select Id, Subject FROM Task];
for (Task t : tasks) {
t.subject = 'static initialization code block';
}
update tasks; // Noncompliant
}
public MyController() {
List<Task> tasks = [Select Id, Subject FROM Task];
for (Task t : tasks) {
t.subject = 'constructor';
}
update tasks; // Noncompliant
}
}
----
=== Compliant solution
[source,apex]
----
public class MyController {
public MyController() {
}
// For example, move the DML statement to a method called when a user clicks a button
public updateTasks() {
List<Task> tasks = [Select Id, Subject FROM Task];
for (Task t : tasks) {
t.subject = 'test';
}
update tasks;
}
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
* Move this DML statement out of the constructor.
* Move this DML statement out of this initialization code block.
=== Highlighting
each DML statement
endif::env-github,rspecator-view[]