Howdy all -
I like parse_strategy: :sync -- I use it in a number of places in my representers. But I just ran into a case where it didn't do what I needed, so I thought I'd post my issue and solution here to see if there's a better way.
I also see the recent conversation b/w Nick and Josh Cohen along with a related GH issue (
https://github.com/apotonick/roar/issues/85). That discussion seems a little more related to collections than properties but maybe there are some parallels with this post.
Up to today, whenever I had used parse_strategy: :sync on a property, the model referred to by the property already existed -- since it existed, the sync strategy was great because it updated that existing model.
Today I had a case where I had a property that could start out as null / empty. Once the property is set, I want to use the :sync strategy so that future changes update the property's model instance. But before it is created, I want roar / representable to make a new object (which it won't do if the parse_strategy is :sync). When :sync is used and there is no existing object, I get errors about not being able to set values on a nil class.
My solution is to set a "getter" on my property that initializes my property to a new instance of the model if it doesn't yet exist.
class ModelA < ActiveRecord::Base
belongs_to :model_b
# side note: even though this says belongs_to, ModelA in my system really "contains" ModelB
# can't have the belongs_to on ModelB as ModelB can be contained by many other
# models, and I have reasons for not using a polymorphic belongs_to
end
class ModelB < ActiveRecord::Base; end
class ModelARepresenter < Roar::Decorator
include Roar::Representer::JSON
property :model_b,
class: ModelB,
decorator: ModelBRepresenter,
getter: lambda { |*| @model_b || ModelB.new },
parse_strategy: :sync
end
If I don't have the getter but do have sync, the code blows up if model_b doesn't exist yet. If I don't have sync, future interactions create a new model_b instead of updating the existing.
The above approach seems to work, but...
- Is there something else I should be doing instead?
- As parse_strategy is being worked on, can Roar / Representable do the ModelB.new step for me if needed?
Thanks!
JP