5

Ho un modello utente locale che utilizza activerecord. L'utente ha un campo email. Ho anche un modello activeresource chiamato task che ha un campo created_by che memorizza l'indirizzo email dell'utente che invia. Mi piacerebbe collegare i due ma sto lottando con la sintassi giusta o anche se è possibile.Come si definisce una relazione tra activerecord e activeresource utilizzando chiavi esterne?

Il ramo principale di ActiveResource non sembra nemmeno supportare la chiave esterna. Ho trovato uno alternative branch ma non riuscivo ancora a far funzionare nulla.

class User < ActiveRecord::Base 
    has_many :tasks 
end 

class Task < ActiveResource::Base 
    belongs_to :user 
    schema do 
    string 'created_by' #email 
    # other fields 
    end 
end 

risposta

1

Non è possibile, ma è possibile simulare implementando i metodi di accesso da soli.

class User < ActiveRecord::Base 
    #has_many :tasks 
    def tasks 
    Task.find(:all, params: {created_by: email}) 
    end 
end 

class Task < ActiveResource::Base 
    #belongs_to :user 
    def user 
    User.where(email: created_by).first 
    end 

    schema do 
    string 'created_by' #email 
    # other fields 
    end 
end 

Questo vi permetterà di scrivere codice come se gli oggetti sono stati associati (cioè User.first.tasks.length). Tuttavia, non sono effettivamente uniti. Ciò significa che chiamare User.first.tasks sta per raggiungere il database, quindi effettuare una richiesta HTTP aggiuntiva per recuperare le attività. A seconda di come è strutturato il tuo codice, potresti incontrare problemi di prestazioni imprevisti.

Inoltre, non è possibile eseguire una singola query per ottenere un utente e Tasks tutte collegate (in quanto si tratta di due archivi di dati separati), e non si può fare cose fantasiose come User.joins(:tasks).where({tasks: field_1: true}).

4

Il codice dovrebbe funzionare bene, dato che si dispone di un attributo user_id sul Task di agire come la chiave esterna, oppure è possibile specificare la chiave esterna in associazione a User modello come segue:

class User < ActiveRecord::Base 
    has_many :tasks, foreign_key: "uid" 
end 

Ora il problema è, non è possibile utilizzare belongs_to su ActiveResource quindi, a meno che non sia necessario recuperare user da un'istanza della classe Task, è sufficiente rimuoverlo e l'altro lato della relazione funzionerà comunque, se è necessario recuperare il user quindi si dovrebbe implementare il proprio metodo finder come segue:

class Task < ActiveResource::Base 
    schema do 
    string 'created_by' #email 
    # other fields 
    end 

    def user 
    @user ||= User.find self.user_id # use the attribute name that represents the foreign key 
    end 

    def user=(user) 
    @user = user 
    self.update_attribute(:user_id, user.id) 
    end 
end 

Questo sarà essenzialmente si comportano allo stesso come ci si aspetterebbe su un modello ActiveRecord, tuttavia questo può essere faticoso se si dispone di più associazioni in modo da poter invece estendere il modulo di ActiveResource aggiungere belongs_to come segue :

module BelongsToActiveResource 

    def self.included(base) 
     base.extend(ClassMethods) 
    end 

    module ClassMethods 

    def belongs_to(name, options = {}) 
     class_eval %(
     def #{name} 
      @#{name} ||= name.to_s.classify.find(name.id) 
     end 

     def #{name}=(obj) 
      @#{name} ||= obj 
      self.update_attribute((name.to_s + "_id").to_sym, @#{name}.id 
     end 
    ) 
    end 

    end 

end 

ActiveResource::Base.class_eval { include BelongsToActiveResource } 

Questo vi permetterà di utilizzare belongs_to su qualsiasi modello ActiveResource.

PS: la soluzione di cui sopra è stato ispirato da https://stackoverflow.com/a/8844932/3770684

+0

Ho provato questo con la patch scimmia avete suggerito, ma quando mi allontano 'User.last.tasks' ottengo 'NoMethodError: metodo non definito 'relation_delegate_class' per l'attività: Classe ' – Simmo

+0

Quali versioni di ruby ​​e rail stai usando? – cousine

+0

Rails 4.1.0 e Ruby 2.1.1 – Simmo

Problemi correlati