Вложенные ассоциации, как подготовить переменные для представлений, рельсы - PullRequest
7 голосов
/ 03 февраля 2012

ходовые рельсы 3.1.3 ...

Я буду использовать простой пример вложенных ассоциаций (не уверен, что это правильный термин). В основном я моделирую базы данных - каждая база данных имеет свои собственные таблицы, а каждая таблица имеет свои собственные столбцы:

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

Мой вопрос, скажем, я хочу отобразить таблицы и столбцы базы данных в виде, что было бы хорошим способом связать эти данные перед передачей их в представление. Как бы выглядел мой контроллер и вид?

Я придумал следующее, но я был бы удивлен, если бы не намного лучший способ сделать это:

Мой контроллер:

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

Мой взгляд:

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

Я также поиграл с использованием этого в контроллере:

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

Однако попытки получить доступ к именам таблиц и столбцов из @database привели меня в бешенство.


UPDATE:

Как правило, я потратил много часов, пытаясь выяснить это, и вскоре после публикации здесь, я думаю, я понял. Спасибо за предложение Майка - это сработало для меня. Кроме того, если я изменю свой собственный метод, используя первый! Метод работает следующим образом:

Контроллер:

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

Вид:

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

1 Ответ

2 голосов
/ 03 февраля 2012

Если я что-то упустил, это на самом деле выглядит нормально для меня, хотя вам не нужны @tables и @columns в контроллере, если вы не используете их для чего-то в представлении.контроллер:

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

просмотр:

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