1 Dec
silvio

silvio il 1 December 2009 parla di Rails Snippet, Risorse, Tutorial

Eager loading e query con condizioni su associazioni polimorfiche e single table inheritance

Come apprendiamo da questo vecchio post di Duccio, a partire dalla versione 2.1.0 di Rails è possibile effettuare query con eager loading su modelli polimorfici, ma tuttora non è possibile applicarci delle condizioni.

Un’interrogazione all’Active Record come la seguente funziona soltanto se il modello Account non è polimorfico:

usr = User.find(:first, :include => :accounts, :conditions => ["accounts.name = 'Principale'"])

Cerchiamo dunque di ovviare al problema dell’ActiveRecord che non consente di applicare condizioni sulla tabella polimorfica inclusa in eager loading.

La modellazione di esempio è la seguente: abbiamo delle “risorse” polimorfiche, da cui ereditano per STI i modelli Picture e Video che dunque sono polimorfici ed ereditari; queste risorse sono associate ai modelli Activity e Article.

class Resource < ActiveRecord::Base
belongs_to :resourceable, :polymorphic => true
end

class Picture < Resource
end

class Video < Resource
end

class Activity < ActiveRecord::Base
has_many :pictures, :as => :resourceable,  :dependent => :destroy
has_many :videos, :as => :resourceable,  :dependent => :destroy
end

class Article < ActiveRecord::Base
has_many :pictures, :as => :resourceable, :dependent => :destroy
end

Cerchiamo adesso di ottenere tutte le immagini associate ad un articolo, di cui ad esempio conosciamo solo parte del titolo.

Con questa modellazione, la seguente interrogazione all’Active Record ritornerebbe un errore:

items = Picture.find(:all,
                     :include => [:resourceable],
                     :conditions => ["LOWER(resourceable.title) LIKE ?", "%titolo_cercato%"])

Per risolvere questo problema è necessario specificare l’inner join, evitando di usare l’include:

items = Picture.find(:all,
                     :joins => "INNER JOIN articles ON articles.id = pictures.resourceable_id",
                     :conditions => ["LOWER(articles.title) LIKE ?", "%titolo_cercato%"])

Per ulteriori approfondimenti guardate la guida Active Record Query Interface e la documentazione delle API

1 Commento a “Eager loading e query con condizioni su associazioni polimorfiche e single table inheritance”

  1. Tiziano il 13 October 2010 alle 11:14 dice:

    Devo dirti la verità… non ho capito nulla !

Scrivi un commento