Manejar Solicitudes Que Actualizan Varias Tablas

«Se llama ‹Lógica de Negocio› »

Empieza simplemente, tienes una relación de mucho a mucho, o posible una relación de uno a mucho o una relación de uno a uno. Y necesitas tocar y usar estas modelas y tablas todas como partes de la transacción misma. A veces, no hay un buen método a normalizar el base de datos sin poner una transacción compleja en la interfaz o software intermedio. Tal vez, quisieras encargar algunos datos de los usarios en una tabla protegida. Las informaciones de identificación personal son subjetan a reglas, y son diferentes a información como un commentario he escribe publicamente. El commentario no necesita una tabla protegida. Y también me gusta minimizar llamas de API.

En este ejemplo, voy a explicar actualizando relaciones con mascotas y usarios en la versión pre-alpha de mi próximo juego es una transacción que actualiza tablas varias.

Terminé eligiendo escribir una controladora personalizada en lugar de poner esa lógica dentro de los modelos como se recomienda en ese artículo stackoverflow porque no necesito lógica compleja actualizar – yo quisiera usar el método incorporado .update como era la intención – Solo necesito tener acesa a un registro seleccionado en una tabla mientras actualizo el otro registro relacionado en la otra tabla.

Para este ejemplo, todo necesitas saber es que la información del usario activo se usa para crear y seguir sesiones, y la mascota está seleccionada separadamente y referenciada por su ID única, y además de cualquier estadísticas vitales de la mascota que se/las influenciada el usario, que el usario toma accion en primer lugar debe reflejada en mejorar o menorar el ‘relación’ atributo de la user_pet_relationship tabla.

Hay una tabla representiva del base de datos postgres debajo:

postgres diagram

Primero, configuremos nuestro solicitud sobre la interfaz para estrucurar nuestros datos asi que están ordenado en las tablas ya queremos usar en el base de datos.

// client/src/components/pet-api/PetActionForm.tsxlet postData = {
        "pet": {
            name: myPets[selectedPet].pet.name,
            hunger: hunger,
            attention: attention
        },
        "user_pet_relationship": {
            relationship: myPets[selectedPet].relationship
        }
    }

pet (mascota) y user_pet_relationship son las dos tablas quiseramos actualizar. La estructura es por tanto un JSON que tiene objetos encajados. Nosotros los separando estes objetos va a hacerlo mucho más fácil acesar estos datos en rails, y enrutar adecuadamente. ¡Asi listos ir y PATCH estos datos!

// client/src/components/pet-api/PetActionForm.tsxfunctionpostPetStats() {
        fetch(`/pet-action-relationship/${myPets[selectedPet].pet.id}`, {
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(postData),
        }).then((response) => {
            if (response.ok) {
                response.json().then((newPetInfo) => {
                    console.log(newPetInfo)
                });
            }
            else {
                response.json().then((errorData) =>console.log(errorData.errors));
            }
        });
    }

Ahora seguimos estos datos a través en rails y mirar a como manejar esta situación.

Primero, rails va a interpretar el endpoint a que hemos PATCH/pet-action-relationship/${myPets[selectedPet].pet.id} traducirá a cualquier /pet-action-relationship/:id ruta, asi podemos mirar a cuál ruta a rails va a usar para aceptar la conexión.

#config/routes.rb#custom routes
  get "/mypets", to:"pets#mypets"
  patch "/pet-action-relationship/:id", to:"combined_endpoint#pet_action_relationship_update"

Acciones PATCH sobre la ruta /pet-action-relationship/:id va a una controladora combined_endpoint y encargar el método /pet-action-relationship_update funciona. Esta situación es diferente de rutas convencionales que esperan endpoints nombrado de acuerdo a modelas tener createshow, o similar acciones a llegar a controladoras nombradas convencionalamentes. Un ejemplo de una ruta convencional sería esta situación, que respuesta con todas las mascotas:

#config/routes.rb

get "/pets", to:"pets#index"

Miramos más cerca a combined_endpoint_controller para cer que está haciendo aquí, y comparar a la controladora pets_controller.

#app/controllers/combined_endpoint_controller.rb# ...# PATCH/PUT /pet-action-relationship/1def pet_action_relationship_updateunless pet_action_form_params_for_relationship[:relationship].blank?
      @pet.update!(pet_action_form_params_for_pet)
      relationship = set_user_pet_relationship
      relationship_update = relationship.update!(relationship: pet_action_form_params_for_relationship[:relationship])
    end
    render json: {pet:@pet, relationship:@user_pet_relationship} 
end

private 

def pet_action_form_params_for_pet
    params.require(:pet).permit(:name, :hunger, :attention, :weight, :height, :species, :diet, :sprite)
  enddef pet_action_form_params_for_relationship
    params.require(:user_pet_relationship).permit(:relationship)
  enddef set_pet@pet = Pet.find(params[:id])
  enddef set_user_pet_relationship@user_pet_relationship = UserPetRelationship.find_by!(pet_id:@pet.id && user_id: session[:user_id])
  end

Para performar todo esto trabajo, necesitemos definar params para los dos objetos dentro del JSON que la interfaz envié al servidor. También envió un callback para obtener el registro dependiente que buscar a la relación de la mascota y el usario activo.

Con eso fuera del camino, dentro del método pet_action_relationship_update primero validamos rapidamente que tenemos todos los datos necesitamos hacer una transacción completa. Si no tenemos, no haciendo. Hay también validaciones sobre los modelos relevantes asegurar que los campos que no tienen null tienen valores.

Desde no cada mascota tiene una relación con cada usario, podemos usar el método normal incorporado .update para actualizar los dos registros que representa las estadísticas vitales cambian (tener menos hambre o mejorar salud) y la relación mejora que llega con buena administración.

El trabajo sobre el base de datos cumpleado, la controladora también no necesita serializar/ordenar compleja para responder la siguiente respuesta a la interfaz, asi que las estadísticas vitales se puede actualizar sobre el tablero del usario.

{"pet":{"name":"Rumi","hunger":0,"attention":10,"id":4,"weight":2.0,"height":8.0,"species":null,"diet":null,"sprite":4,"created_at":"2022-12-02T00:34:23.893Z","updated_at":"2022-12-06T16:13:34.396Z"},"relationship":{"relationship":9,"id":1,"user_id":1,"pet_id":4,"player_is_owner":true,"bio":null,"guestbook":null,"created_at":"2022-12-02T00:34:23.924Z","updated_at":"2022-12-06T19:25:51.888Z"}}

Gracias para leyendo. Estoy emocionado para añadadir más características a este juego y oficialmente empezar actualizar y publicar esta proyecta. Si te interesa leer más o me apoyas y los tipos de proyectas los que trabajo, por favor escribe un commentario debajo. Puedes también contactarme en LinkedIn.

Related Posts