2010-07-12 4 views
0

Voici le code généré par des rails:RoR: Comment modifier le contrôleur pour accepter la mise à jour de plusieurs paramètres seulement?

def update 
    @user = User.find(params[:id]) 

    respond_to do |format| 
    if @user.update_attributes(params[:user]) 
     flash[:notice] = 'User was successfully updated.' 
     format.html { redirect_to(@user) } 
     format.xml { head :ok } 
    else 
     format.html { render :action => "edit" } 
     format.xml { render :xml => @user.errors, :status => :unprocessable_entity } 
    end 
    end 
end  

Mais je ne veux pas l'utilisateur de mettre à jour l'utilisateur tout, supposons que mon utilisateur a fname, lname et le sexe, au lieu de supprimer le sexe de la vue, Je veux limiter que la méthode de mise à jour accepte UNIQUEMENT fname et lname seulement, si il/elle veut mettre à jour le genre, je ne lui permettrai pas de le faire. Comment puis-je empêcher l'utilisateur de le faire? Je vous remercie.

+0

Etes-vous sûr de vouloir cela au niveau du contrôleur/modèle? De ma propre expérience, j'essaierais d'éviter cela en utilisant JavaScript ou en utilisant plusieurs formulaires (un formulaire pour la mise à jour par genre, un pour la mise à jour du nom, tous les deux utilisent la même mise à jour), surtout si vous voulez bien. "Vous ne pouvez pas changer votre nom et votre sexe en même temps" est vraiment étrange à lire dans une documentation API. –

Répondre

1

Utilisez les paramètres Hash des update_attributes

@user = User.find(params[:id]) 
@user.update_attributes(:fname=>params[:user][:fname], :lname=>params[:user][:lname]) 
+0

désolé, je voudrais savoir, que signifie l'utilisateur @@? pourquoi pas @utilisateur seulement. Je vous remercie. – Tattat

+0

Il est faux, cela devrait ressembler à '@ user.update_attributes (...)', comme vous l'avez utilisé dans votre exemple. – Veger

+0

@Tattat: - c'est juste une faute de frappe ici désolé. mais si je ne me trompe pas, la variable '@@' est utilisée pour représenter 'Global Variables in rails' – Salil

0

Vous pouvez delete attributs indésirables du param[:user] Hash:

# ... 
attributes = params[:user] 
gender = attributes.delete :gender 
raise SomeError unless gender.blank? 
if @user.update_attributes(attributes) 
    # ... 
end 
# ... 

Ce code supprime :gender du Hash et vérifie si elle est remplie si. donc, une exception est soulevée. Bien sûr, vous pouvez donner un avertissement gentil ou ignorer en silence le fait que le sexe a été rempli.

3

ou ajouter une méthode personnalisée @user.update_only(), ce qui le rend aussi plus facile à réutiliser dans des contextes différents ...

class User 
    def update_only(attrs = {}, *limit_to) 
    update_attributes(attrs.delete_if { |k,v| !limit_to.include?(k.to_sym) }) 
    end 
end 

Ensuite, faire quelque chose le long des lignes de

@user.update_only(params[:user], :fname, :lname) 
+0

Je dois dire que j'aime cette idée.Ce serait une belle extension pour ActiveRecord (ou peut-être une belle extension pour update_attributes, en utilisant un: excepté hash peut-être). –

+0

et il gère de manière transparente attr_protected/accessible - n'hésitez pas à l'emballer comme plugin, ou l'ajouter à AR :: Base (aurait du sens) – lwe

+0

Bonne idée pour une solution générale – bjg

2

Il existe deux méthodes ActiveRecord qui viennent très pratique dans des cas comme ceux-ci, attr_protected et attr_accessible.

-vous les utiliser comme ceci:

class MyModel < ActiveRecord::Base 
    attr_accessible :fname, :lname #Allow mass-assignment 
    attr_protected :secret #Do not allow mass-assignment 
end 

model = MyModel.new(:fname => "Firstname", :lname => "Lastname", :secret => "haha") 
puts model.fname # "Firstname" 
puts model.lname # "Lastname" 
puts model.secret = nil # Can not be set through mass-assignment 
model.secret = "mysecret" # May only be assigned like this 
puts model.secret # "mysecret" 

Cependant, si vous avez besoin de cette fonctionnalité à un endroit, puis la solution de Salil fonctionnera tout aussi bien.

Une chose à noter est que vous devez utiliser attr_acessible aux attributs qui sont OK de whitelist à masse assign, et de faire tout autre attribut protégé. Ce faisant, vous empêchez les gens de mettre à jour des données qu'ils ne sont pas censés toucher.

Voir the docs pour plus d'informations.

+0

Ceci est la meilleure réponse de tous ceux fournis , pas de piratage et fonctionne au niveau du modèle, où ce type de code devrait être. – Faisal

Questions connexes