reform: Using nested objects doesn't populate decedent items/models. (Plus saving strategies)

If I do something like

class TagForm < Reform::Form
  property :category
  property :primary_label do
    property :name
  end
  collection :aliased_labels do
    property :name
  end
end

test = TagForm.new Tag.new.tap &:build_primary_label
stuff = { "category" => "classification", "primary_label_attributes" => { "name" => "Rumor" }, "aliased_labels_attributes" => [ { "name" => "Market Talk" }, { "name" => "Speculation" } ] }
test.validate stuff

I get the following results. I’m not sure if this is “by design” / intentional or not. To me it just seems a little inconsistent and maybe a bit baffling as a new user

test.model.primary_label.name # nil
test.primary_label.model.name # nil
test.primary_label.name # "Rumor"

I would have expected all 3 to produce “Rumor”, rather than a first two end up with nil. Especially given that test.model has all it’s attributes set, it seems odd that items within nested properties do not set these details (I would have thought it would have been possible to do this lazily when you access test.primary_label.model - I’m not too sure what you’d do in the case of test.model.primary_label as this might be a trickier case to deal with.

Even if this “by design” I wonder if this is worth documenting along with the reasons/motivations?

The original reason I bring this up is also is that I’d like to come up with a generic way to be able to save objects when dealing with nesting, in the same way that accepts_nested_attributes_for is able to. My guess is that 80% of the time users will want to mimic accepts_nested_attributes_for as for the most part this is normally what is needed, and it’s just a handful of times where a more fine control is needed (maybe a good idea to create some sort of “save policy” system to handle the bulk of generic cases when saving nested models). For the most part accepts_nested_attributes_for does the job for me apart from a few cases when it comes to deal with error handling (because errors in nested model objects shouldn’t be handled by the top most / active / original callee model object.

On this note I think would would be handy would be a way to have some sort of utility method that returns child model objects from the nesting process in some sort of collection so it would be easy to iterate over and save them. I guess the other issue at hand here is how we deal with assigning foreign keys, such as making sure that tag_id is assigned when saving the labels. (Obviously this would need to support several layers / levels of nesting)

Plus for a large part, reform for me and I guess for a number of other users is seems to be more about having an alternative to StrongParams (which in my mind is an ugly solution), along with the ability to break down models / decorate models with specific validations/logic for specific contexts.

I did skim over the source and notice you have a model.save call as a default action when saving and have placed a comment to state that you plan to deal with case of dealing with nested model objects.

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 20 (11 by maintainers)

Most upvoted comments

Excuses, nothing but lame excuses! 😉

Look, that stuff is tested: https://github.com/apotonick/reform/blob/1923f30c2aead2bc6e0772952479f9388a220f9a/test/errors_test.rb#L62

If you experience a different behaviour, please do report it!