12

Je voudrais avoir un tableau de bord pour afficher le résumé de plusieurs modèles, et je l'ai implémenté en utilisant Presenter sans ses propres données. J'utilise une classe ActiveModel (sans table de données):Comment passer l'argument à la méthode déléguée dans Rails

class Dashboard 
    attr_accessor :user_id 
    def initialize(id) 
    self.user_id = id 
    end 

    delegate :username, :password, :to => :user 
    delegate :address, :to => :account 
    delegate :friends, :to => :friendship 

end 

par le délégué, je veux être en mesure d'appeler Dashboard.address et retourner Account.find_by_user_id(Dashboard.user_id).address.

Si Dashboard était une classe ActiveRecord, alors j'aurais déclaré Dashboard#belongs_to :account et délégué travaillerais automatiquement (à savoir, compte connaîtrait il devrait revenir attribut d'adresse du compte avec user_id est égal à to user_id dans l'instance de tableau de bord). Dashboard n'est pas une classe ActiveRecord, donc je ne peux pas déclarer belongs_to. J'ai besoin d'un autre moyen de dire au compte de rechercher le bon enregistrement.

Existe-t-il un moyen de résoudre ce problème? (Je sais que je peux simuler Dashboard pour avoir une table vide, ou je peux réécrire les méthodes d'instance de l'utilisateur à des méthodes de classe qui prennent argument, mais ces solutions sont toutes des hacks).

Merci.

+0

Cela n'a pas beaucoup de sens. Qu'est-ce que 'id'? Est-ce censé être un nombre? (Vous ne pouvez pas 'send (" 123 ")', ce n'est pas un nom de méthode valide.) Vous ne pouvez pas utiliser Dashboard.user_id' avec 'attr_accessor: user_id', l'un est une classe et l'autre est l'instance. .. S'il vous plaît clarifier et donner des exemples de la façon dont vous vous attendez à ce que cela fonctionne. –

+0

Salut Andy, peut-être que je ne suis pas assez clair. Veuillez noter qu'il ne s'agit pas d'une classe ActiveRecord :: Base régulière. Par conséquent, j'ai besoin d'un attribut pour contenir id de current_user. (Je ne veux pas garder cet identifiant de façon permanente cependant). Par délégué, je veux être en mesure d'appeler Dashboard.address et de récupérer Account.find_by_user_id (Dashboard.user_id) .address. J'ai tenté de déléguer cette fonction à la classe Account, mais j'ai besoin de passer la valeur user_id à Account d'une manière ou d'une autre, afin qu'elle sache avec quelle instance de compte elle devrait travailler. – AdamNYC

Répondre

10

Lorsque vous écrivez delegate :address, :to => :account, cela crée une nouvelle méthode address sur tableau de bord qui appelle essentiellement la méthode account sur le même objet et appelle address sur le résultat de cette méthode account. Ceci est (très grossièrement) semblable à l'écriture:

class Dashboard 
... 
    def address 
    self.account.address 
    end 
... 
end 

Avec votre classe actuelle, tout ce que vous avez à faire est de créer une méthode account qui renvoie le compte avec le user_id correct:

class Dashboard 
    attr_accessor :user_id 
    def initialize(id) 
    self.user_id = id 
    end 

    delegate :username, :password, :to => :user 
    delegate :address, :to => :account 
    delegate :friends, :to => :friendship 

    def account 
    @account ||= Account.find_by_user_id(self.user_id) 
    end 
end 

Cette vous permettrait d'accéder à l'adresse comme ceci:

dashboard = Dashboard.new(1) 
# the following returns Account.find_by_user_id(1).address 
address = dashboard.address 
+0

Merci Benoit. C'est exactement ce que je cherche. – AdamNYC

+0

@AdamNYC N'hésitez pas à demander des éclaircissements si vous avez des doutes sur le code ci-dessus, je serai heureux de mettre des explications supplémentaires. –

Questions connexes