2010-11-21 4 views
2

J'ai un problème de rails très difficile et j'ai pensé à demander de l'aide. La situation est la suivante:Rails - Validation personnalisée qui nécessite des informations current_user

J'utilise une authentification reposante pour mon modèle utilisateur. Maintenant, l'utilisateur a un champ nommé 'gold' qui est une valeur numérique. Il existe un autre modèle nommé Book qui a été créé à l'aide d'échafaudages.

Ce que je veux faire est simple, mais je ne peux pas voir une façon de le faire. Je veux ajouter une validation où si l'or de l'utilisateur n'est pas, disons 100, ils ne peuvent pas créer une nouvelle entrée de livre (à partir de la vue standard d'échafaudage).

Maintenant, le problème est que j'ai besoin d'informations current_user afin de valider cela à partir de mon modèle. J'ai besoin de cela pour obtenir l'identifiant de l'utilisateur et donc obtenir leur quantité d'or ainsi. Je ne peux pas trouver un bon moyen (le cas échéant) de le faire.

Une autre idée était de le faire à partir d'un contrôleur. Cependant, la norme « si @ book.save » bloc ne me permet pas vraiment d'insérer mes propres messages d'erreur (à l'intérieur échafaudage créer):

if not User.has_the_needed_gold(current_user, 100) 
    flash[:goldError] = 'You do not have the needed gold to create this book.' 
#end 


respond_to do |format| 
    if @book.save 
    flash[:notice] = 'Book was successfully created.' 
    format.html { redirect_to(@book) } 
    format.xml { render :xml => @book, :status => :created, :location => @book } 
    else 
    format.html { render :action => "new" } 
    format.xml { render :xml => @book.errors, :status => :unprocessable_entity } 
    end 
end 

Maintenant, je ne peux pas sortie ce message et abandonner l'enregistrement de la nouvelle livre aussi. J'ai essayé d'ajouter ma propre erreur à la base, mais elle a été effacée (après sauvegarde je suppose). Je suis assez confus avec la situation et j'ai cherché pendant quelques heures sans résultats.

Si quelqu'un peut aider, s'il vous plaît le faire, vous me épargner beaucoup d'ennuis :)

Thanx pour la lecture!

+0

Comment définissez-vous vos modèles. Le livre appartient-il à l'utilisateur et l'utilisateur a-t-il de nombreux livres? – s84

+0

En fait, ça devrait être le contraire dans mon cas. Un utilisateur a un livre mais un livre peut appartenir à de nombreux utilisateurs. Bien que je n'aie pas encore ajouté les définitions pour le moment. Cette question sonne une cloche cependant. Accéder à l'information via la relation, était trop bête pour penser à cela:/Je vais jeter un oeil – Spyros

Répondre

2

Vous pouvez définir un attribut :user_gold virtuel pour Book, réglez dans le contrôleur où vous avez accès à current_user puis incorporer dans votre validation Book.

+0

Et ce fut la solution! Directement sur place, beaucoup merci :) – Spyros

+1

Cela ne semble pas être une bonne idée ... vous associez un peu les couches du modèle et du contrôleur, ce qui fait que le modèle dépend d'une variable définie dans le contrôleur pour fonctionner correctement. –

+0

Josian, je ne vois vraiment pas d'autre moyen de le faire. – Spyros

2

Regardez l'utilisateur en cours de validation. Il est probable que la recherche d'utilisateur aura été mise en cache par ActiveRecord, donc ce n'est pas un coup de performance pour le faire. Essayez quelque chose comme ceci:

class Book 

    validate :check_gold 

    def check_gold 
    user = User.find(self.user_id) 
    self.errors.add(:user_id => "#{user.name} doesn't have enough gold!") if user.nil? or (user.gold < 100) 
    end 
end 
+0

J'ai effectivement obtenu ce que j'attendais, une erreur sur user_id (méthode non définie 'user_id '). Peu importe comment j'essaie, je ne peux pas obtenir le current_user au modèle Book. – Spyros

+0

Si user_id n'est pas défini dans le modèle Book, vous n'utilisez pas d'association, comme je le pensais. Y a-t-il un champ nommé "user_id" dans votre table "books"? Les utilisateurs sont-ils supposés posséder des livres? –