Full disclosure: I don’t consider myself any close to an expert on Delegated Types and accepts_nested_attributes. Please point out any misconceptions if any.
(for reference: Add accepts_nested_attributes_for support for delegated_type by xtr3me · Pull Request #41717 · rails/rails · GitHub)
Say I have my model:
class Foo
delegated_type :detail, %w[Bar Baz]
accepts_nested_attributes_for :detail
end
Now, AFAIU I’m supposed to use it this way:
Foo.new(detail_type: "Bar", detail_attribues: {attr1: ""})
So far so good, but if I do this Foo.new(detail_type: "User", detail_attribues: {})
I get an error that User does not have attr1
attribute.
This feels to me that I’m exposing too much to the users (by manipulating “detail_type” value they can make my app to instantiate and attempt to assign an attribute to any model, maybe even any objects).
If that’s the case – I can imagine I can just not accept detail_type
in my controller, but make up some bogus type (e.g., detail_alias
) and map it to actual types:
Foo.new(
detail_type: {"bar" => "Bar", "Baz" => "baz"}.fetch(params[:detail_alias])
...
But would that be an intended way to use delegated types with nested attributes? Maybe we need some sort of richer config, like:
delegated_type :detail, {bar: Bar, baz: Baz} # the key is an alias
I’m very interested in your experience/opinions
Edit:
Since writing the original post, I found about the reject_if:
for nested attributes:
accepts_nested_attributes_for :detail,
reject_if: :illegal_detail_type?
def illegal_detail_type?(_attributes)
!self.class.detail_types.include?(detail_type)
end
Would that be the intended way to make nested attributes safer?