ruby-on-rails ruby refactoring controller

ruby on rails - ¿Cómo ordenarías esta lógica de controlador?



ruby-on-rails refactoring (6)

Desglosarlo en declaraciones if anidadas.

if params[:concept][:consulted_legal] == ''0'' if params[:concept][:consulted_marketing] == ''1'' @concept.attributes = { :status => ''Awaiting Compliance Approval'' } else @concept.attributes = { :status => ''Awaiting Marketing & Legal Approval'' } end else if params[:consulted_marketing] == ''1'' @concept.attributes = { :status => ''Awaiting Marketing Approval'' } else @concept.attributes = { :status => "Pending Approval" } end end

Tengo un poco de lógica en un controlador que establece el estado de un objeto si se cumplen ciertas condiciones:

if params[:concept][:consulted_legal] == 0 && params[:concept][:consulted_marketing] == 1 @concept.attributes = {:status => ''Awaiting Compliance Approval''} elsif params[:concept][:consulted_marketing] == 0 && params[:concept][:consulted_legal] == 1 @concept.attributes = {:status => ''Awaiting Marketing Approval''} elsif params[:concept][:consulted_marketing] == 0 && params[:concept][:consulted_legal] == 0 @concept.attributes = {:status => ''Awaiting Marketing & Legal Approval''} else @concept.attributes = {:status => ''Pending Approval''} end

que comparto entre crear y actualizar acciones. ¿Cómo harías para refaccionar esta maldad? Buscando las mejores prácticas.

Nuevo en la programación y dispuesto a limpiar mi código.

TIA.


Eso parece ser lógica de negocios, por lo que debería estar en el modelo realmente.

Es probable que su modelo necesite un par de atributos: consulted_legal y consulta_marketing, y un método para establecer el estado cuando cualquiera de ellos se modifique de la siguiente manera:

before_update :set_status def set_status if consulted_legal && consulted_marketing status = "Pending Approval" elif consulted_legal && !consulted_marketing status = "Awaiting Marketing Approval" elif !consulted_legal && consulted_marketing status = "Awaiting Legal Approval" elif !consulted_legal && !consulted_marketing status "Awaiting Marketing & Legal Approval" end true # Needs to return true for the update to go through end


Esta es mi opinión sobre ella. Yo lo llamo Super DRY.

statuses = [ [''Awaiting Marketing & Legal Approval'',''Awaiting Compliance Approval''], [''Awaiting Marketing Approval'',''Pending Approval''] ] {:status => statuses[params[:concept][:consulted_legal].to_i][params[:concept][:consulted_marketing].to_i]}

Alternativamente, un enfoque más convencional: extenso pero legible:

status = if params[:concept][:consulted_legal] == "0" if params[:concept][:consulted_marketing] == "1" ''Awaiting Compliance Approval'' else ''Awaiting Marketing & Legal Approval'' end else if params[:concept][:consulted_marketing] == "0" ''Awaiting Marketing Approval'' else ''Pending Approval'' end end @concept.attributes = {:status => status}

Nota : parece que su código original está verificando los valores de las casillas de verificación. Los valores en hash params son siempre Strings , no Fixnum s, por lo que mi código compara cadenas. Si por alguna razón comparar lo de Fixnum es lo que se requiere para su situación, solo Fixnum las comillas de los números.


Esto parece una regla de negocios para mí. Como tal, es posible que desee envolverlo en una función:

string GetConceptStatus(bool consulted_legal, bool consulted_marketing) { if (consulted_legal && consulted_marketing) { return "Pending Approval"; } if (consulted_legal && !consulted_marketing) { return "Awaiting Marketing Approval"; } if (!consulted_legal && consulted_marketing) { return "Awaiting Legal Approval"; } if (!consulted_legal && !consulted_marketing) { return "Awaiting Marketing & Legal Approval"; } }

Esto también separa los detalles de cómo se codifican los booleanos en su interfaz a partir de la implementación real de la regla de negocios.

Pero la estructura real del código me parece buena, ya que probablemente modele mejor la regla comercial.


Puede hacer que su código sea menos dependiente de ambas condiciones y hacerlo mucho más flexible.

waiting_on = [] waiting_on << ''Compliance'' unless params[:concept][:consulted_marketing] waiting_on << ''Legal'' unless params[:concept][:consulted_legal] status = waiting_on.empty? ? "Awaiting #{waiting_on.join('' & '')} Approval" : ''Pending Approval'' @concept.attributes = {:status => status}

Versión para crear y actualizar sin filtro:

def create set_concept_status_attribute ... end def update set_concept_status_attribute ... end private def set_concept_status_attribute waiting_on = [] waiting_on << ''Compliance'' unless params[:concept][:consulted_marketing] waiting_on << ''Legal'' unless params[:concept][:consulted_legal] status = waiting_on.empty? ? "Awaiting #{waiting_on.join('' & '')} Approval" : ''Pending Approval'' @concept.attributes = {:status => status} end

O con un before_filter:

before_filter :set_concept_status_attribute, :only => [:create, :update] def create ... end def update ... end

Si puede moverlo a su vista, se ve aún mejor:

module ConceptHelper def get_concept_status ... end end <%= get_concept_status %>


puede pensar que la lista de departamentos consultados es un concepto suficientemente fijo para justificar las variables llamadas consulta_marketing, etc., pero para el crecimiento y la sequedad (en cierto modo), prefiero una lista de departamentos.

Lo que realmente tiene aquí es un flujo de trabajo o máquina de estados, creo que una lista de departamentos con transiciones daría como resultado el código más limpio y creíble.

¡El código es información! Modele sus datos y el código será trivial.