Running Rails 3.1.3...
I'll use a simple example of nested associations (not sure if this is correct term). Basically I'm modelling databases - each database has its own tables and each table has its own columns:
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
My question is, say I want to display a database's tables and columns in a view, what would be a good way of bundling this data before passing it to the view. Basically, what would my controller and view look like?
I've come up with the following, but I would be surprised if there is not a much better way of doing this:
My controller:
class DatabasesController < ApplicationController
def show
@database = Database.find_by_id(params[:id])
@tables = @database.tables
@columns = @database.tables.columns
end
end
My view:
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 %>
I've also played around with using this in the controller:
@database = Database.where(:id => params[:id]).includes(:tables => [:columns])
However trying to access the table and column names from @database has driven me mad.
UPDATE:
Typically, I have spent many hours trying to figure this out and shortly after I post here, I think I get it. Thanks for the suggestion miked - this worked for me. Also, if I amend my own method by using the first! method it works as follows:
Controller:
def show
@database = Database.where(:id => params[:id]).includes(:tables => [:columns]).first!
end
View:
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 %>
Unless I'm missing something, this actually looks okay to me, though you don't need the @tables and @columns in the controller unless you are really using them for something in the view.
controller:
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
view:
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 %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With