2009-04-07 19 views
7

Al escribir el método "crear" para un objeto en una aplicación de Ruby on Rails, he usado dos métodos. Me gustaría utilizar un método por el bien de un código más limpio y consistente. Voy a enumerar los dos métodos a continuación. ¿Alguien sabe si uno es mejor que el otro? Si es así, ¿por qué?Al crear un objeto en Ruby on Rails, ¿qué método de guardado prefiere y por qué?

Método 1:

def create1 
    # is this unsecure? should we grab user_id from the session 
    params[:venue]['user_id'] = params[:user_id] 

    begin 
    venue = Venue.create(params[:venue]) 
    @user_venues = @user.venues 
    render :partial => 'venue_select_box', :success => true, :status => :ok 
    rescue ActiveRecord::RecordInvalid 
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity 
    end 
end 

Método 2:

def create2 
    # is this unsecure? should we grab user_id from the session 
    params[:venue]['user_id'] = params[:user_id] 

    venue = Venue.new(params[:venue]) 
    if venue.save 
    @user_venues = @user.venues 
    render :partial => 'venue_select_box', :success => true, :status => :ok 
    else 
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity 
    end 
end 
+0

Creo que quieres decir "crear!" no "crear" en el Método 1. "crear" no generará una excepción; simplemente devuelve falso en los errores de validación. –

+0

tiene la razón, gracias por señalar – Tony

Respuesta

4
class VenuesController < ApplicationController 
    def create 
    @venue = @user.venues.create!(params[:venue]) 
    render :partial => 'venue_select_box', :success => true, :status => :ok 
    end 

    rescue_from ActiveRecord::RecordInvalid do 
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity 
    end 
end 

Usando @user.venues de esta manera asegurar que el ID de usuario siempre será un valor apropiado. Además, ActiveRecord protegerá el campo :user_id de la asignación durante el transcurso de la llamada #create!. Por lo tanto, los ataques desde el exterior no podrán modificar :user_id.

En sus pruebas, puede verificar que al hacer una POST para: crear, se genera una excepción ActiveRecord :: RecordInvalid.

+0

del punto del caos de que "las excepciones no deberían usarse para condiciones de rutina" es bueno. Sin embargo, Rails ha decidido lo contrario: "rescue_from ActiveRecord :: RecordInvalid" es una práctica común. –

3

Soy de la escuela de pensamiento que las excepciones no deben ser utilizados para las condiciones de rutina, así que diría que la segunda es mejor.

2

Depende. Si espera que todas las instrucciones de creación funcionen, use la primera, ya que la falla en crear y guardar es excepcional y posiblemente sea una condición de la cual el programa no puede recuperarse fácilmente. Además, si usa la integridad relacional (foreign_key_migrations por RedHill Consulting), esto arrojará excepciones sobre las violaciones de claves extranjeras, por lo que probablemente desee detectarlas cada vez que las cree o actualice.

El segundo es viable, y es bueno si la consulta no tiene éxito es algo que espera como parte del funcionamiento diario de esa acción en particular.

Además, su código de comentario sobre la sesión es inseguro - la sesión es el lugar para poner el user_id. Siempre que esté comprobando que el usuario ha sido autenticado antes de hacer cualquier otra cosa, estará bien.

+0

. Dado que se trata de una acción de creación, ¿está diciendo que la versión 1 es buena si tengo validación del lado del cliente, pero la versión 2 es mejor si uso la validación del lado del servidor? – Tony

+0

No del todo ... con pocas excepciones, * siempre * desea validar en el lado del servidor, como precaución de seguridad (la validación del lado del cliente siempre puede ser deshabilitada por un atacante malintencionado) ... (dividiéndose en dos comentarios) –

+0

Mi regla empírica es si uso save() cuando espero que la operación se complete sin una restricción de DB, y create() cuando espero que pueda ... ¿eso ayuda? También siempre implemento un controlador global de excepciones para detectar errores perdidos. –

1

Estoy totalmente de acuerdo con el comentario de Don. Pero incluso iría un paso más allá con la parte user_id y la establecería como filtro anterior en el modelo.

Cuestiones relacionadas