Ich möchte die Params-Sammlung vom Controller an das Modell übergeben, um die Filter- und Sortierbedingungen zu analysieren. Hat mit einer Methode in das Modell, das die Parameter aus dem Controller nimmt MVC brechen?
Antworten
Zu viele Anzeigen?Das kommt darauf an. Sie übergeben einen Hash von Daten an das Modell und sagen: "Machen Sie daraus einen Sinn".
class Model < ActiveRecord::Base
def update_from_params(params)
....
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_params(params)
end
end
Das ist in Ordnung. Aber Sie werden vielleicht feststellen, dass Sie dies bei vielen verschiedenen Aktionen tun wollen. Es ist unwahrscheinlich, dass Sie die Parameter in jedem Fall genau gleich machen können, also brauchen Sie mehrere Methoden in Ihrem Modell, eine für jede Aktion:
class Model < ActiveRecord::Base
def update_from_update_params(params)
# do stuff
end
def update_from_settings_params(params)
# do different stuff
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_update_params(params)
end
def change_settings
...
@model.update_from_settings_params(params)
end
end
Das ist nicht in Ordnung und Sie zwingen das Modell, die Arbeit des Controllers zu übernehmen. Ein vernünftiger Mittelweg besteht darin, eine Methode auf Ihrem Modell zu erstellen, die einen kanonischen Datenhash akzeptiert, und dann zwischen den Parametern und dem kanonischen Hash im Controller zu übersetzen:
class Model < ActiveRecord::Base
def update_from_data(hash)
validate_data!(hash)
# do stuff
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_data(translate_update_params)
end
def change_settings
...
@model.update_from_data(translate_change_settings_params)
end
end
Allerdings sollten Sie darauf achten, dass Sie das Format des Datenhashs, den das Modell akzeptiert, sorgfältig dokumentieren. Wir gehen sogar so weit, dass wir eine YAML-Validierungsbibliothek verwenden ( Rx ), um sicherzustellen, dass das Modell nur gültige Daten annimmt.
Entschuldigung für die lange Antwort, aber ich habe keine Zeit, eine kürzere zu schreiben ;).
Ich würde sagen, das tut es auf jeden Fall.
Der params-Hash enthält eine Menge Dinge, die Ihre Modelle nicht brauchen sollten. Im Grunde sind Sie ignorieren die C-Teil von MVC. Was Sie tun möchten, wird funktionieren (aka es wird ausgeführt), aber ich denke, Sie sollten in den Parametern als getrennte Einheiten übergeben.
Ich würde vorschlagen, eine Teilmenge von Parametern zu übergeben, so dass Sie nur das übergeben, was das Modell benötigt.
Im Controller:
# in controller
def search
Model.search(params[:search][:options])
end
Stellen Sie einfach sicher, dass Ihre Eingaben 'namespaced' sind, damit Sie einen verschachtelten Hash erhalten:
<!-- in view -->
<input type='text' name='search[options][keywords]' />
<input type='text' name='search[options][conditions]' />
<input type='text' name='search[options][sort]' />
Dann in Ihrem Modell:
def self.do_search(criteria)
Rental.search(criteria[:keywords],
:per_page => self.per_page,
:page => page,
:conditions => criteria[:conditions],
:order => criteria[:sort])
end
Ich glaube nicht, dass das der Fall ist, aber ich bin ja auch kein Eisenbahnveteran. Typischerweise wird der Params-Hash im Controller verwendet und diese Aktion kann oder kann nicht lesen und schreiben Modellinformationen, so dass ich denke, wenn die Params durch eine Methode, die das Modell gehören zu gehen, wäre es die gleiche Sache sein.
So oder so ich denke, Sie müssen noch die Parameter durch einen Controller zu senden, also warum nicht Ihre Verarbeitung dort tun, dann senden Sie die verarbeiteten Daten an das Modell durch eine Methode des Modells?