12

Vorrei avere un dashboard per visualizzare il riepilogo di più modelli e l'ho implementato utilizzando Presenter senza i propri dati. Io uso una classe ActiveModel (senza tabella di dati):Come passare argomento per delegare metodo in 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 

dal delegato, voglio essere in grado di chiamare Dashboard.address e tornare Account.find_by_user_id(Dashboard.user_id).address.

Se Dashboard è una classe ActiveRecord, allora avrei potuto dichiarato Dashboard#belongs_to :account e delegato avrebbe funzionato automaticamente (vale a dire, account saprebbe deve restituire attributo di indirizzo dal conto con user_id uguale to user_id in caso Dashboard).

Ma Dashboard non è una classe ActiveRecord, quindi non è possibile dichiarare belongs_to. Ho bisogno di un altro modo per dire a Account di cercare il record giusto.

C'è un modo per superare questo problema? (So ​​che posso simulare Dashboard per avere una tabella vuota, o posso riscrivere i metodi di istanza di User in metodi di classe che prendono argomenti.) Ma queste soluzioni sono tutti hack).

Grazie.

+0

Questo non ha molto senso. Che cos'è 'id'? Questo dovrebbe essere un numero? (Non puoi 'send (" 123 ")', non è un nome di metodo valido.) Non puoi usare 'Dashboard.user_id' con' attr_accessor: user_id', uno è una classe e l'altro è l'istanza. .. Si prega di chiarire e dare esempi di come ti aspetti che funzioni. –

+0

Ciao Andy, potrebbe essere che non sono abbastanza chiaro. Si noti che questa non è una classe ActiveRecord :: Base normale. Pertanto, ho bisogno di un attributo per contenere id di current_user. (Io non voglio mantenere questo ID in modo permanente però). Per delegato, desidero poter chiamare Dashboard.address e recuperare Account.find_by_user_id (Dashboard.user_id) .address. Ho tentato di delegare questa funzione alla classe Account, ma ho bisogno di passare il valore user_id all'account in qualche modo, in modo che sappia con quale istanza di account dovrebbe funzionare. – AdamNYC

risposta

10

Quando si scrive delegate :address, :to => :account, questo crea un nuovo address metodo su Dashboard che chiama in pratica il metodo account sullo stesso oggetto e quindi chiama address sul risultato di questo metodo account. Questo è (molto approssimativamente) simile alla scrittura:

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

con la classe corrente, tutto ciò che dovete fare è creare un metodo account che restituisce il conto con la corretta user_id:

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 

Questo consentirebbe di accedere all'indirizzo come questo:

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

Grazie Benoit. Questo è esattamente quello che sto cercando. – AdamNYC

+0

@AdamNYC Non esitare a chiedere chiarimenti se hai qualche dubbio sul codice di cui sopra, metterò volentieri spiegazioni aggiuntive. –