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