2009-07-08 6 views
2

J'écris mon premier plugin de rails et je pourrais utiliser un peu d'aide. D'une manière très simplifiée, je voudrais permettre au développeur de spécifier une valeur que je peux compter à travers une tâche de rake. Je pense à quelque chose comme ça ...Écrire un plugin ActiveRecord pour Rails

class User < ActiveRecord::Base 
    monitor "Users", count 
    monitor "Active Users", count("activated_at != NULL") 
end 
  1. Je suppose que le moniteur doit être une méthode de classe de ActiveRecord :: Base mais comment/où dois-je préciser dans mon plug-in?
  2. L'argument de la fonction monitor ne doit pas être la valeur mais un bloc de code à exécuter. Je ne suis pas sûr de la meilleure façon de le spécifier et de garder la syntaxe simple. Peut-être que ce sera monitor "Active Users", {count "activated_at != NULL"}?
  3. Je préférerais que le développeur n'ait pas à spécifier User.count, juste count, c'est-à-dire qu'il récupère automatiquement la classe (et les blocs seront appelés sur la classe et non sur l'instance). Si ce n'est pas possible, je suppose qu'il n'y a aucune raison de mettre les instructions du moniteur dans le modèle (voir # 5).
  4. Le comptage réel de ces valeurs (c'est-à-dire, l'exécution des blocs) sera effectué par une tâche rake hors ligne. Que devrait faire la fonction monitor pour rendre ces blocs disponibles pour la tâche rake? Les stocker dans une variable de classe?
  5. Peut-être que les instructions de surveillance n'ont pas besoin d'être spécifiées dans le modèle. Peut-être que ça encombre le site, donc je serais heureux de trouver d'autres endroits pour les mettre.

Je ne fais que dessiner mes idées en ce moment et essayer de comprendre ce qui est/n'est pas possible dans Ruby. Toute aide appréciée.

Mise à jour: Je vais essayer d'être plus clair sur le but du plugin. Je veux que le développeur soit capable de définir des mesures qui devraient être surveillées par la tâche rake. La tâche rake va parcourir ces métriques et écrire les valeurs dans un fichier (j'ai un peu simplifié). La tâche de rake sera très simple, quelque chose comme rake monitors:update (à savoir, pas params nécessaire)

Répondre

0

Merci pour toute votre aide, mais je suis allé avec une approche différente (extraite ci-dessous). Au lieu de spécifier les attributs dans les modèles, j'ai utilisé une approche vue dans la gemme every. J'ai placé un fichier ruby ​​"de dashboard.rb" dans mon répertoire config:

dashboard "Users", User.count 
dashboard "Activated Users", User.count('activated_at') 

Mon lib se compose de deux fonctions:

def self.dashboard(name, attribute) 
     puts "** dailydashboard: #{name} = #{attribute.to_s}" 
    end 

    def self.update(file) 
    eval File.read(file) 
    end 

Fondamentalement, ma tâche Rake appelle update, qui charge dashboard.rb et eval uates et appelle à plusieurs reprises la fonction dashboard, qui sort ceci:

** dailydashboard: Users = 2 
** dailydashboard: Activated Users = 1 

Désolé pour aller dans les maisons al Ittle peu. Pour les choses en arrière-plan/hors ligne, cela semble être une approche très simple et fait ce dont j'ai besoin. Merci quand même pour vôtre aide!

0

Essayez de regarder le code pour named_scope

Quelle est la conception de la tâche de coupe ressemblant?

rake monitor: utilisateur: utilisateurs actifs?

OT:

activated_at is not null est le SQL que vous voulez

Venez y penser, pourquoi ne pas oublier de définir le moniteur, et il suffit d'utiliser named_scopes? où au lieu de retourner un select *, vous faites un select count(*)

+0

Merci, vous avez raison sur le SQL - c'était juste un exemple. Je pense que named_scopes sera très utile mais cela ne résoudra pas tout à fait mon problème. J'ai mis à jour la question avec plus d'informations sur ce que le plugin essaie d'atteindre. – ideasasylum

1

Vous mettez probablement la définition des tâches râteau au mauvais endroit. Le modèle doit uniquement contenir une logique qui est valide pour l'un de ses consommateurs, et ne pas se préoccuper d'applications spécifiques comme rake. Une meilleure approche peut être de définir certaines étendues nommées dans vos modèles, et de spécifier les actions que vous souhaitez être disponibles dans vos tâches rake. Les étendues nommées peuvent être réutilisées facilement dans d'autres zones de votre application.Un modèle peut ressembler à ceci (notez que ceci est une caractéristique Rails - aucun travail de votre part):

class User < ActiveRecord::Base 
    named_scope :active_users, :conditions => "activated_at != NULL" 
end 

Et vous alors créer un DSL très simple qui peut être utilisé dans les fichiers de râteau (par exemple dans lib/tasks/count.rake). Quelque chose qui vous permettra de le faire, par exemple:

require "your-plugin" 
namespace :count do 
    # Make your plugin rewrite this internally to User.count 
    YourPlugin::CountTask.new :users 

    # Make your plugin rewrite this to User.active_users.count 
    YourPlugin::CountTask.new :users, :active_users 

    # Perhaps allow usage of blocks as well? 
    YourPlugin::CountTask.new :users, :complicated do 
    User.count(complex_conditions) 
    end 
end 

Cela devrait alors fournir à l'utilisateur des tâches nommées count:users, count:users:active_users et count:users:complicated.

+0

Je prends le point vous-même et Omar a fait à propos de named_scopes. Définitivement utile. J'ai mis à jour la question avec plus d'informations. J'espère avoir plus de sens cette fois. – ideasasylum

0

Quelque chose comme cela devrait faire ce que vous voulez:

module Monitored 
    @@monitors = [] 
    def self.monitor(name, method) 
    @@monitors.push [name, method] 
    end 
    def self.run_monitor(name) 
    send @@monitors.select{|m| m[0] == name}[0][1] 
    end 
end 

Non testé, mais vous avez l'idée, je l'espère.

Questions connexes