2012-02-03 6 views
7

carriles de rodadura 3.1.3 ...asociaciones anidadas, cómo preparar las variables para las vistas, los carriles

voy a utilizar un ejemplo sencillo de asociaciones anidados (no estoy seguro si esto es correcto plazo). Básicamente estoy modelar bases de datos - cada base de datos tiene sus propias tablas y cada mesa tiene sus propias columnas:

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 

Mi pregunta es, digo que quiero mostrar tablas y columnas de una base de datos en una vista, lo que sería una buena forma de agrupar estos datos antes de pasarlos a la vista. Básicamente, ¿cómo se verían mi controlador y mi vista?

que he llegado a la siguiente, pero me sorprendería si no hay una mejor manera de hacer esto:

Mi controlador:

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

Mi opinión:

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 %> 

también he jugado un poco con el uso de este en el controlador:

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

Sin embargo, tratar de acceder a los nombres de tabla y columna de @database me ha vuelto loco.


ACTUALIZACIÓN:

Por lo general, he pasado muchas horas tratando de resolver esto y poco después he puesto aquí, creo que lo entiendo. Gracias por la sugerencia del micrófono: esto funcionó para mí. Además, si modifico mi propio método, ¡utilizo el primero! método funciona de la siguiente manera:

controlador:

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

Me alegro de poder ayudar. Gracias por señalar el uso de .first en su solución final. También actualizaré mi solución. Sin él, la referencia en la vista arrojaría un error de método indefinido cuando la vista intenta acceder a la (s) asociación (es). ¡Aclamaciones! – miked

Respuesta

2

A menos que me falta algo, en realidad esto se ve bien a mí, aunque usted no' Necesito @tables y @columns en el controlador a menos que realmente las esté usando para algo en la vista.

controlador:

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 %> 
Cuestiones relacionadas