10

Quando si lavora con un'associazione polimorfica, è possibile eseguire un inclusione su sottomodelli che sono presenti solo in alcuni tipi?Ruby on Rails:: include in associazione polimorfica con submodels

Esempio:

class Container 
    belongs_to :contents, :polymorphic => true 
end 
class Food 
    has_one :container 
    belongs_to :expiration 
end 
class Things 
    has_one :container 
end 

Nella vista ho intenzione di voler fare qualcosa di simile:

<% c = Containers.all %> 
<% if c.class == Food %> 
    <%= food.expiration %> 
<% end %> 

Pertanto, mi piacerebbe carico desiderosi scadenze quando carico fino c perché so che avrò bisogno di ognuno di loro. C'è un modo per farlo? Basta definire un normale: include mi fa errori perché non tutti i tipi chiusi hanno una scadenza submodel.

risposta

24

risposta a cura

di recente ho scoperto che Rails supporta il caricamento desiderosi di associazioni polimorfiche quando si filtra dalla colonna tipo polimorfico. Quindi non c'è bisogno di dichiarare associazioni false.

class Container 
    belongs_to :content, :polymorphic => true 
end 

Ora la tua ricerca Container da container_type.

containers_with_food = Container.find_all_by_content_type("Food", 
          :include => :content) 

containers_with_thing = Container.find_all_by_content_type("Thing", 
          :include => :content) 

Vecchio risposta

Si tratta di un hack in quanto non v'è alcun modo diretto per includere gli oggetti polimorfici in una query.

class Container 
    belongs_to :contents, :polymorphic => true 
    # add dummy associations for all the contents. 
    # this association should not be used directly 
    belongs_to :food 
    belongs_to :thing 
end 

Ora la tua ricerca Container da container_type.

containers_with_food = Container.find_all_by_content_type("Food", 
          :include => :food) 

containers_with_thing = Container.find_all_by_content_type("Thing", 
          :include => :thing) 

che si traduce in due SQL chiamate al database (in realtà è 4 chiamate come rotaie esegue uno SQL per ogni :include)

Non v'è alcun modo per fare questo in uno SQL come avete bisogno di colonna diverso impostato per diversi tipi di contenuto.

Caveat: Le associazioni fittizie su Content classe non devono essere utilizzati direttamente come si tradurrà in risultati inaspettati.

E.g: Diciamo che il primo oggetto nella tabella contents contiene cibo.

Content.first.food # will work 
Content.first.thing 

La seconda chiamata non funzionerà. Potrebbe darti un oggetto con lo stesso ID dell'oggetto Food indicato da Content.

+0

Ho aggiornato la mia risposta sulla base di alcune nuove informazioni, dare un'occhiata. –

+1

In quale versione di ActiveRecord funziona il caricamento ansioso delle associazioni polimorfiche? Non funziona per me in 3.2.3 – nicholaides

+0

@nicholaides Dovrebbe funzionare in 3.2.3. Il caricamento impaziente si verifica solo quando si filtra per la colonna di tipo polimorfico. Qual è l'errore che hai incontrato? –