2010-04-20 5 views
2

Je viens d'être référé à stackoverflow par un ami ici pour aider avec un problème que j'ai. Je suis assez novice en ruby ​​on rails et je travaille sur un projet collaboratif où nous avons un script (medal_worker.rb) qui doit se dérouler à intervalles réguliers pour récompenser les différentes médailles en fonction de la participation et du succès sur notre site web. Une des nouvelles médailles sur lesquelles je travaille récompense les gens pour des «jalons». Pour ce problème, disons que nous voulons leur donner des médailles lorsqu'ils font des commentaires de 100, 1000 et 10000. Je voudrais le faire en utilisant named_scopes du modèle User (user.rb) pour me donner des listes filtrées des utilisateurs que je recherche.Ruby on Rails: using named_scopes

Ma question est: Comment puis-je trouver les utilisateurs qui n'ont pas les médailles respectives pour le niveau de commentaire de milestone respectif (de préférence en utilisant les named_scopes du modèle User)?

Voici un Exerpt de mon fichier model_worker.rb:

def award_comment_milestone(comments) 
    users = Users.frequent_comment_club_members(comments).not_awarded_medal(Medal.find_by_id(medal.id)) 
    for user in users do 
     award_medal(medal, nil, user) if @award 
    end 
end 

Voici où je suis à des named_scopes dans le modèle utilisateur (user.rb):

named_scope :frequent_comment_club_members, lambda { |*args| 
     {:include => comment_records, :conditions => ['comment_records.comment_type = ? and comment_records.comments >= ?', 'User', (args.first || 0)]} 
} 

named_scope :not_awarded_medal, lambda { |medal| 
    {:include => :awards, :conditions => ['awards.medal_id not in (select awards.medal_id from awards where awards.medal_id = ?)", medal.id] } 
} 

Cela ne fonctionne pas comme je le voudrais, mais je ne sais pas si le problème est dans le named_scopes ou comment je passe des arguments ou quoi. Merci.

+0

Qu'est-ce qui ne fonctionne pas exactement? – jonnii

Répondre

1

Votre named_scopes a l'air bien. Sauf que vous commencez par une seule apostrophe et que vous terminez par une double apostrophe dans l'instruction de condition not_awarded_medal.

EDIT:

Rapportez-. Votre not_awarded_medal named_scope est éteint.

Essayez quelque chose comme ceci:

named_scope :not_awarded_medal, lambda { |medal_id| 
    { :include => :awards, 
    :conditions => [ 
     "? not in (select awards.id from awards where awards.user_id = users.id)", medal_id 
    ] 
    } 
} 

non testé

Maintenant ceci suppose que vous avez les relations suivantes:

User: has_many :awards Award: belongs_to :user

Si vous utilisez has_many :through alors vous allez devoir changer le SQL pour regarder la table de jointure (users_awards).

-

Mais je ne vois deux choses dans la fonction award_comment_milestone.

Quel est le paramètre entrant dans award_comment_milestone? Est-ce un tableau de commentaires ou est-ce un compte de commentaires? Où est également défini medal?

Si comments est un tableau, vous devez passer comments.length dans frequent_comment_club_members. Si c'est le nombre alors je le renommerais à comments_count ainsi la prochaine personne peut comprendre la logique plus rapidement.

Quelques observations générales:

  • not_awarded_medal devrait juste prendre un medal_id et non l'ensemble de l'objet (pas besoin de faire plusieurs requêtes)
  • Pourquoi faites-vous Medal.find_by_id(medal.id)? Vous avez déjà l'objet médaille.
+0

Merci pour le retour rapide. La citation simple vs la double citation est probablement comment j'ai tapé le code ici, mais une bonne observation. En ce qui concerne le paramètre passé dans award_comment_milestone, je n'ai pas spécifié mais cette fonction est appelée trois fois chaque fois en passant dans l'une des trois valeurs (100, 1000, 10000) pour les différents jalons à vérifier. En supposant que 100 est passé, je veux trouver le nombre d'utilisateurs qui ont plus de 100 commentaires, mais pas encore attribué la médaille pour cette étape (même pour 1000 et 10000). Peut-être l'appeler comment_count ou comment_milestone vs commentaires est une bonne idée. – jadavis

+0

Voir ma modification. Je pense que vous avez des problèmes avec le 'not_awarded_medal' named_scope –

+0

merci pour l'aide – jadavis