Reputation: 207
I'm trying to find an optimal way to model my database.
Background:
I currently have two rails Models, one called Environment
and the other called StatusUpdate
.
I have a program that sits on various servers and submits StatusUpdates
for Environments
. These updates contain four pieces of information about an environment.
I have an index screen that shows me all Environments
. (Modeled below)
I store the ten most recent StatusUpdates
and anything > 10 is deleted upon receiving a new one.
Basic index layout
-- Environment1 --Status_Field_1--Status_Field_2--Status_Field_3--Status_Field_4--
-- Environment2 --Status_Field_1--Status_Field_2--Status_Field_3--Status_Field_4--
-- Environment3 --Status_Field_1--Status_Field_2--Status_Field_3--Status_Field_4--
-- Environment4 --Status_Field_1--Status_Field_2--Status_Field_3--Status_Field_4--
Current Schema
Environment(name):has_many StatusUpdates
StatusUpdate(field1, field2, field3, field4): belongs_to Environment
Environments Controller
def index
@environments = Environment.paginate(page: params[:page])
end
I then render @environments
using a partial.
The Question
The current schema seems appropriate, but I suspect I would have to make an extra call to the database in the EnvironmentsController during the index function. Do I change the Environment
schema to include fields 1 - 4? Or is there a way to execute Environment.paginate
while retrieving the most recent StatusUpdate from the database for each Environment?
H-man's recommendation sounds perfect, but I can't figure out why I am receiving an unexpected tLabel error in my model with the has_one association he recommended. For reference:
class Environment < ActiveRecord::Base
has_many: status_updates
has_one: current_status, -> { order: 'created_at DESC' }, class_name: 'StatusUpdate'
end
Rails 4.0.2
Upvotes: 0
Views: 451
Reputation: 2347
class Environment < ActiveRecord::Base
has_many :status_updates
has_one :current_status, -> {order 'created_at DESC'}, class_name: 'StatusUpdate'
end
Then you can do this:
def index
@environments = Environment.includes(:current_status).paginate(page: params[:page])
end
This will eager-load the current status update for all environments in one go. I assume you're using Rails 4 since you didn't mention the version #. If you're using an older version of rails, use this instead:
has_one :current_status, class_name: 'StatusUpdate', order: 'created_at DESC'
Upvotes: 1