2014-12-29 6 views
13

Mi sono reso conto di qualcosa di strano quando ho provato a caricare un'immagine tramite la gemma paperclip per il mio modello utente (sotto l'attributo avatar). Per qualche motivo, User.update e @ user.update_attributes si comportano diversamente. Qualcuno sa perché è così?Rails Paperclip: update vs. update_attributes

#using @user.update_attributes(user_avatar_params) 
def update_profile_pic 
    @user = User.find(params[:id]) 
    @user.update_attributes(user_avatar_params) 
    puts @user.avatar_file_name.nil? # prints false as expected 
    respond_to do |format| 
     format.html { redirect_to :back } 
     format.js 
    end 
end 

#using User.update(@user.id, user_avatar_params) 
def update_profile_pic 
    @user = User.find(params[:id]) 
    User.update(@user.id, user_avatar_params) 
    puts @user.avatar_file_name.nil? # prints true although successfully saves 
    respond_to do |format| 
     format.html { redirect_to :back } 
     format.js 
    end 
end 

Ed ecco la mia forti params nella user_controller.rb

def user_avatar_params 
    params.require(:user).permit(:avatar) 
end 

UPDATE

Così, dopo aver ricevuto risposte rapide e impressionante questo è quello che ho imparato:

User.update restituisce l'oggetto risultante se è stato salvato correttamente nel database o meno. Pertanto, User.update(@user.id, user_avatar_params) non aggiorna la variabile @user se non si effettua l'assegnazione. @user.update_attributes(user_avatar_params) cambia implicitamente la variabile @user.

La soluzione per questo a lavorare con il metodo di aggiornamento è quello di fare @user = User.update(@user.id, user_avatar_params)

+1

Come affinità menzionate User.update restituisce l'oggetto in base al record che ha aggiornato. Quindi in pratica non è lo stesso oggetto nella memoria a cui l'utente var punta. Prova: user = User.update (user.id, user_avatar_params) e credo che otterrai lo stesso risultato in entrambi i casi. BTW, penso che valore atteso in 'user.avatar_file_name.nil?' dovrebbe essere falso, non vero –

+0

Grazie per la cattura @RoaringStones. Ho corretto il post. Sì, quando uso '' '@user = User.update (user.id, user_avatar_params)' '' stampa false come mi aspettavo. –

risposta

12

ActiveRecord.update ha un comportamento che può essere gettando voi fuori: "Aggiorna un oggetto (o più oggetti) e lo salva al database, se passate le convalide. L'oggetto risultante viene restituito se l'oggetto è stato salvato correttamente nel database o meno. " http://apidock.com/rails/ActiveRecord/Base/update/class

Tuttavia, l'aggiornamento_attributi restituirà semplicemente false.

Entrambe utilizzano le convalide a livello di modello e quindi entrambe devono salvare o non salvare allo stesso modo. Tuttavia, i valori di ritorno saranno diversi.

Come @RoaringStones sottolineato, la soluzione è quella di utilizzare "user = User.update (user.id, user_avatar_params)"

+0

Sì, ho provato a testarli nello stesso identico scenario. –

28

Per quel che vale, come di Rails 4.0.2, #update restituisce false se il aggiornamento fallito, non semplicemente l'oggetto per il quale l'aggiornamento non è riuscito. Di ulteriore nota, #update_attributes è semplicemente un alias di #update ora.