2009-08-16 6 views
16

J'ai une requête SQL qui n'est pas spécifique à une table et je ne sais pas comment la gérer avec Ruby On Rails.Requête SQL personnalisée sans table correspondante

Voici ma requête SQL (vous n'avez pas besoin de le comprendre):

SELECT type, actor_id, events.created_at, photo_id, photos.user_id FROM 
(SELECT 'comment' AS type, user_id AS actor_id, created_at, photo_id FROM comments 
UNION 
SELECT 'classification' AS type, user_id AS actor_id, created_at, photo_id FROM classifications) 
AS events 
INNER JOIN photos ON photo_id = photos.id 
WHERE user_id = #{@user.id} 
ORDER BY created_at DESC 
LIMIT 9

j'ai essayé de créer un modèle et d'utiliser un find_by_sql:


class RecentActivity ActiveRecord::Base 
    attr_accessor :type, :actor_id, :created_at, :photo_id, :user_id 
end 

Je reçois:

Mysql::Error: Table 'mysite_development.recent_activities' doesn't exist: SHOW FIELDS FROM `recent_activities`

Comment puis-je éviter ce message? Y a-t-il une solution alternative?

+0

Que voulez-vous dire, Je vois des tables dans cette requête. –

+0

Il n'y a pas de table MySql nommée recent_activities et correspondant au modèle. – collimarco

Répondre

36

Vous pouvez récupérer une connexion db directement à partir de ActiveRecord :: Base, mais ce n'est pas aussi utile que d'étendre AR :: Base, car des méthodes utiles comme sanitize_sql sont protégées.

class ComplexQueries < ActiveRecord::Base 
    def self.my_query 
    # Notice how you can, and should, still sanitize params here. 
    self.connection.execute(sanitize_sql(["select * from foo limit ?", 10])) 
    end 
end 

results = ComplexQueries.my_query 
results.each_hash{|h| puts h.inspect} 
+0

Merci! Exactement ce que je cherchais. – collimarco

+0

Moi aussi! En fait, la seule bizarrerie ici est avec la dernière ligne - vous aurez probablement envie de faire: results.each_hash {| h | print "# {h} \ n"} Sur ma requête, .inspect n'affiche rien. – aronchick

+0

Si h contient des données, alors l'impression ou l'impression des résultats de h.inspect fonctionnerait tous les deux. Avez-vous oublié les "puts" devant h.inspect? – jdl

0

Si vous voulez créer des classes (modèles) qui ne sont pas une base de données support sur vous avez besoin de ne pas dire qu'ils sont héritant de ActiveRecord.

Do

class RecentActivity 

Au lieu de

class RecentActivity < ActiveRecord::Base 

Cela étant dit, il pourrait encore être utile d'obtenir quelques informations supplémentaires sur ce que vous essayez de faire: par exemple, si vous voulez avoir quelque chose comme "commentaires" ou "images" sur plusieurs choses différentes comme un article, ou un profil de quelqu'un ou blogpost tout au sein de la même application, je vous recommande de vérifier PolyMorphic Associations.

+0

Ce dont j'ai besoin est d'exécuter la requête ci-dessus et d'instancier certains objets avec son contenu. – collimarco

7

Vous pouvez également saisir la connexion ActiveRecord et appelez select_all: "pas spécifique table"

ActiveRecord::Base.connection.select_all('select * from foo').each do |e| 
    puts e.inspect 
end 
Questions connexes