Wenn Daten vorhanden sind, die in einen Status übergehen, tritt diese Art von Code häufig auf.
erb:view.html.erb
<%#Es scheint, dass keine Genehmigung erteilt werden kann, wenn der Status des Berichts 1 oder 2 ist, aber wie sind die Status 1 und 2?%>
<%= button_tag('Die Genehmigung', disabled: (report.state == 1 || report.state == 2)) %>
reports_controller.rb
def accept
report = Report.find(params[:id])
#Für die Behandlung ist dieselbe bedingte Anweisung wie view erforderlich!
if report.state == 1 || report.state == 2
flash[:error] = 'Kann nicht genehmigen'
redirect_to root_url
end
report.state = 3 #Genehmigungswert!
report.save!
end
Wenn Sie eine Konstante verwenden, verbessert sich diese ein wenig, aber ...
erb:view.html.erb
<%= button_tag('Die Genehmigung', disabled: (report.state == Report::STATE_DRAFT || report.state == Report::STATE_TRASH)) %>
reports_controller.rb
def accept
report = Report.find(params[:id])
#Immerhin ist die gleiche bedingte Anweisung wie view erforderlich!
if report.state == Report::STATE_DRAFT || report.state == Report::STATE_TRASH
flash[:error] = 'Kann nicht genehmigen'
redirect_to root_url
end
report.state = Report::STATE_APPROBAL
report.save!
end
report.rb
class Report < ApplicationRecord
#Wenn viele Spalten Konstanten erfordern, sind viele Konstanten erforderlich.
#Außerdem ist der Anwendungsbereich zu groß und es ist schwierig, den Zweck zu erkennen.
STATE_DRAFT = 1
STATE_TRASH = 2
STATE_APPROBAL = 3
end
Es gibt eine Möglichkeit, ActiveRecord :: Enum anstelle einer Konstante zu verwenden, aber es löst nicht die Notwendigkeit derselben bedingten Anweisung an verschiedenen Stellen ... Dies kann durch Hinzufügen einer Methode zum ActiveRecord-Modell gelöst werden.
report.rb
class Report < ApplicationRecord
STATE_DRAFT = 1
STATE_TRASH = 2
STATE_APPROBAL = 3
def can_accept?
state != STATE_DRAFT && state != STATE_TRASH
end
end
Aber das ist der Weg zum Fat Model ... Damit ...
Vermeiden Sie die Fettmodellierung von ActiveRecord-Modellen und erstellen Sie Zustandsübergangsklassen mit klaren Verantwortlichkeiten. Es wäre schön, wenn die bedingte Anweisung eine Statusänderungsmethode namens "report_state.to_approval" mit dem Gefühl "report_state.approval_in_next" hätte? "[^ 1](kann sie sich im genehmigten Zustand befinden).
[^ 1]: Der Methodenname soll "Gibt es eine Genehmigung im nächsten Bundesstaat?" Sein. Da es sich jedoch um einen englischen, verdammt verschiedenen Fisch handelt, gibt es möglicherweise andere gute Methodennamen.
reports_controller.rb
def accept
report = Report.find(params[:id])
report_state = report.state_object
#Sauber
unless report_state.approval_in_next?
flash[:error] = 'Kann nicht genehmigen'
redirect_to root_url
end
#Dies ist ein einfaches Beispiel mit nur einer Spalte, aber selbst wenn die Verarbeitung des Zustandsübergangs kompliziert ist, zu_*Kann in der Methode versteckt werden!
new_report_state = report_state.to_approval
report.state = new_report_state.state
report.save!
end
report.rb
class Report < ApplicationRecord
# state_object=Es kann zweckmäßig sein, eine Methode zu erstellen
def state_object
ReportState.new(state)
end
end
Die eigentliche ReportState-Klasse sieht folgendermaßen aus.
report_state.rb
class ReportState
attr_accessor :state
#Verschieben Sie Konstanten aus der Report-Klasse. Es passt immer besser
DRAFT = 1
TRASH = 2
APPROBAL = 3
def initialize(state)
self.state = state
end
def approval_in_next?
state != DRAFT && state != TRASH
end
def to_approval
raise 'Illegaler Staatsübergang!' unless approval_in_next?
self.class.new(APPROBAL)
end
end
Selbst wenn die Bedingungen, die genehmigt werden können, kompliziert werden oder der Prozess des Zustandsübergangs in den Genehmigungsstatus kompliziert wird, müssen Sie hier nur noch Änderungen vornehmen!
Dieser Eintrag ist für Zustandsübergangsdiagramm, Zustandsübergangstabelle in Anforderungsanalyse-gesteuertes Design. #% E7% 8A% B6% E6% 85% 8B% E9% 81% B7% E7% A7% BB% E5% 9B% B3% E7% 8A% B6% E6% 85% 8B% E9% 81% B7% E7% A7% BB% E8% A1% A8) wurde neu organisiert und in allgemeine Inhalte umgeschrieben. Es ist eine lange Geschichte, aber es ist eine Geschichte über DDD-ähnliche Dinge in Rails.
Recommended Posts