2012-02-03 10 views
7

Rails 3.1.3 in corso ...associazioni nidificati, come preparare le variabili per le viste, rotaie

userò un semplice esempio di associazioni annidati (non so se questo è corretto termine). Fondamentalmente sto modellando banche dati - ogni database ha le sue tabelle e ogni tavolo ha le sue colonne:

class Database < ActiveRecord::Base 
    has_many :tables 
end 

class Table < ActiveRecord::Base 
    belongs_to :database 
    has_many :columns 
end 

class Column < ActiveRecord::Base 
    belongs_to :table 
end 

La mia domanda è, diciamo voglio visualizzare tabelle e colonne di un database in una vista, quello che sarebbe un buon modo di raggruppare questi dati prima di passarli alla vista. Fondamentalmente, quale sarebbe il mio controller e la mia vista?

mi è venuta in mente quanto segue, ma sarei sorpreso se non c'è un modo molto migliore di fare questo:

mio regolatore:

class DatabasesController < ApplicationController 
    def show 
    @database = Database.find_by_id(params[:id]) 
    @tables = @database.tables 
    @columns = @database.tables.columns 
    end 
end 

mio punto di vista:

Database: <%= @database.database_name %><br /> 
<% @tables.each do |table| %> 
    Table: <%= table.table_name %><br /> 
    <% table.columns.each do |column| %> 
    Column: <%= column.column_name %><br /> 
    <% end %> 
<% end %> 

ho anche giocato un po 'con l'utilizzo di questo nel controller:

@database = Database.where(:id => params[:id]).includes(:tables => [:columns]) 

Tuttavia, provare ad accedere ai nomi di tabella e colonna da @database mi ha fatto impazzire.


UPDATE:

In genere, ho trascorso molte ore cercando di capire questo fuori e poco dopo ho posto qui, penso che ho capito. Grazie per il suggerimento miked - questo ha funzionato per me. Inoltre, se modifico il mio metodo usando il primo! metodo funziona come segue:

Controller:

def show 
    @database = Database.where(:id => params[:id]).includes(:tables => [:columns]).first! 
end 

Vista:

Database: <%= @database.database_name %><br /> 
<% @database.tables.each do |table| %> 
    Table: <%= table.table_name %><br /> 
    <% table.columns.each do |column| %> 
    Column: <%= column.column_name %><br /> 
    <% end %> 
<% end %> 
+0

Contento di aver potuto aiutare. Grazie per aver segnalato l'uso di .first sul tuo finale finale - aggiornerò anche la mia soluzione. Senza di esso, il riferimento nella vista genererebbe un errore di metodo non definito quando la vista tenta di accedere alle associazioni. Saluti! – miked

risposta

2

A meno che non mi manca qualcosa, questo sembra in realtà va bene a me, anche se si don' t sono necessari @tables e @columns nel controller, a meno che non li si utilizzi realmente per qualcosa nella vista.

regolatore:

class DatabasesController < ApplicationController 
  def show 
    @database = Database.find(params[:id], :include=>{:tables => [:columns]}) #eager load 
    #or: @database = Database.where(:id => params[:id]).includes(:tables => [:columns]).first #eager load 
    #or: @database = Database.find(params[:id]) #queries will be executed in the view 
  end 
end 

vista:

Database: <%= @database.database_name %><br /> 
<% @database.tables.each do |table| %> 
  Table: <%= table.table_name %><br /> 
  <% table.columns.each do |column| %> 
    Column: <%= column.column_name %><br /> 
  <% end %> 
<% end %>