2010-07-22 5 views
3

J'ai deux modèles qui ne sont pas liés (dans le sens db) mais qui ont des colonnes communes (Nom, Email, etc.).Comment mélanger deux modèles de rails en une seule recherche?

Class Account < ActiveRecord::Base 

end 


Class LegacyAccount < ActiveRecord::Base 

end 

Pour diverses raisons, je ne peux pas les fusionner en un seul modèle ou faire des STI. Mais je voudrais une vue simple qui affiche tous les enregistrements des deux modèles dans une belle table (éventuellement triée par un champ commun comme "nom").

Est-il possible de faire une recherche/requête à partir des deux modèles? Ou puis-je faire deux trouvailles et fusionner les tableaux résultants afin qu'ils soient triés? Puis-je utiliser un modèle intermédiaire pour fusionner les deux?

+0

Êtes-vous désireux de travailler tous de trouver de la magie? ou peut-il être quelque chose comme "Account.find_by_account_number" et il retournera soit un compte ou un LegacyAccount –

Répondre

1

Si elles ne peuvent pas être rejoints par la base de données, vous pouvez peut-être définir un objet Ruby qui fusionne les enregistrements et retourne un hachage.

class AccountView 
    def self.find_all 
    accounts = [] 
    Account.find(:all).each do |account| 
     accounts << {:name => account.name, ... } 
    end 
    LegacyAccount.find(:all).each do |account| 
     accounts << {:name => account.name, ... } 
    end 
    return accounts 
    end 
end 

Ou, définissez les attributs sur AccountView et retourne un tableau de AccountView objets.

+0

J'ai fini par faire un mélange de la réponse de Karl et de cette réponse. J'ai donné à celle-ci la solution parce que j'aime la faire emballer dans une classe. – Callmeed

-1
@accounts = Account.find(:all, :include => :legacy_account) 

ou Rails3 rejoindre le style

@accounts = Account.all.joins(:legacy_account) 
+0

Non, cela ne semble pas fonctionner. Je pense: include/.joins ne fonctionne que pour les modèles qui ont une association. Ces deux modèles n'ont aucune association. Je voudrais simplement les combiner en une seule trouvaille et vue. – Callmeed

6

solution la plus simple est juste de fusionner les tableaux, puis il suffit d'utiliser Array méthodes de tri de quelque sorte:

@accounts = (LegacyAccount.all + Account.all).sort{|x,y| x.name <=> y.name} 

Vous pourriez probablement écrire une méthode de recherche personnalisée dans votre modèle Account pour rendre cela plus facile si vous pouviez appelez Account.find_all ou quelque chose.


Il existe une autre solution possible en utilisant SQL:

@accounts = Account.find_by_sql("SELECT * FROM accounts UNION SELECT * FROM legacy_accounts") 

qui fonctionne en termes de SQL pur, mais je ne suis pas sûr de Rails. Je suppose qu'il traitera tous les LegacyAccounts comme s'ils étaient des comptes normaux. Je ne suis pas sûr de ce qui arrivera si LegacyAccounts a des colonnes que les comptes n'ont pas, non plus.

Sinon, vous pouvez essayer quelque chose ici: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html

Ce dernier 2 solutions sont difficiles, donc je ne les essayer si vous avez quelque chose de très spécifique à l'esprit.

1

Juste mes 2 cents voici ce que je l'ai utilisé pour le site flux RSS:

(Model1.latest + Model2.latest).sort_by(&:created_at).reverse 
Questions connexes