-
-
Save krisleech/4087333 to your computer and use it in GitHub Desktop.
class Domain::Trip | |
include Virtus | |
include ActiveModel::Validations | |
include ActiveModel::Conversion | |
extend ActiveModel::Naming | |
attribute :id | |
attribute :name | |
attribute :sections, Array[Section], :default => [] | |
end | |
class Persistence::Trip < ActiveRecord::Base | |
def self.find_by_id(id) | |
record = super(id) | |
Domain::Trip.new(record.attributes).tap do |trip| | |
trip.sections = record.sections.map { |section_record| Domain::Trip::Section.new(section_record.attributes) } | |
end | |
end | |
end |
def show | |
@trip = Persistence::Trip.find(params[:id) | |
end |
- @trip.sections.each do |section| | |
= section.name |
I've played with Virtus and nested hashes, AR#attributes does not return a deep hash, but as you say it could easily be done. I think my problem is more do with the API of the persistence class - what should the different calls to the persistence class look like. If say I want to fetch a trip and all its associations (e.g show action) versus just the trip (e.g index action).
I think you probably have two different value objects there then: a TripSummary
for the index page, with a shallow cut of the data, and a Trip
with the deep set of data. I'd just put the queries for those behind two separate methods.
Thanks - I like the idea of having TripSummary
, after all it does not need to contain any validations, or anything else that acts on state changes, its being used in a read-only context. I guess I need to get over fear of adding classes which have overlapping responsibilities, its marginally less DRY but simpler than trying cram everything in to one class.
You can give Virtus a nested hash, and it will hydrate the chid objects in the graph automatically.
I'm not sure if you can get AR to give you a nested hash of attributes out of the box, but it would be trivial to add that.