store_model
store_model copied to clipboard
Nested Attributes?
Hi @DmitryTsepelev,
are you planning to add the accept_nested_attributes_for
function to the store_model?
Hi @exsemt!
Please take a look at the discussion in this issue #7, where we've discussed an ability to update store_model
as a nested association. Do you want the same thing or you have one store_model
inside another?
Yes, I have one store_model
inside another:
class Concept
include StoreModel::Model
attribute :id, :integer
attribute :name, :string
attribute :values, ConceptValue.to_array_type
# fix for nested attributes
def values_attributes=(values)
self.values = values.values
end
end
class ConceptValue
include StoreModel::Model
attribute :name, :string
...
end
It will be greate to have some like accept_nested_attributes_for
and not to write values_attributes=
Got it, that sounds like a nice addition 🙂 Feel free to come up with a PR if you're interested in playing with the gem, otherwise I'll take a look at it next week
Hi @exsemt!
I've added a couple of tests for nested attributes, and it looks like for your case
concept.update(id: 1, name: "name", values: [{ name: "name }])
or
concept = Concept.last
concept.values = [ConceptValue.new(name: "name)]
concept.values
should work of the box. What usecase am I missing here?
Correct, that works, but it does not work as an Active Record Nested Attributes
so values_attributes
:
concept.update(id: 1, name: "name", values_attributes: [{ name: "name }])
Here we go https://github.com/DmitryTsepelev/store_model/pull/17 - could you please try it out before I merge it in?
Released 0.4.0 with accept_nested_attributes_for
support
Thanks! Sorry that took so long time to check it, it works fine for .to_type
association, but it does not work for a .to_array_type
, because you get from HTML form a hash with a key as counter of association object and value - the object hash. e.g.:
class Concept
include StoreModel::Model
attribute :id, :integer
attribute :name, :string
attribute :values, ConceptValue.to_array_type
end
# does not work
concept.update(id: 1, name: "name", values_attributes: [{ "0" => { "name" => "name 1" }}, { "1" => { "name" => "name 2" }}])
Here is a PR with a possible fix. The only thing is that in Rails only Hash and Array are accepted, so the param should be either { "0" => { "name" => "name 1" }, "1" => { "name" => "name 2" }]
or [{ "name" => "name 1" }, { "1" => { "name" => "name 2" }]
. Could you please make sure your form sends [{ "0" => { "name" => "name 1" }}, { "1" => { "name" => "name 2" }}]
?
Thx! Works! 👍
I tried adding validatation on nested attributes but it gave me the error "NoMethodError (undefined method `type_for_attribute' for ...)"
class Form
include StoreModel::Model
attribute :id, :integer
attribute :for, :string
attribute :inputs, FormInput.to_array_type
validates :id, :for, presence: true
validates :inputs, store_model: true
end
class FormInput
include StoreModel::Model
attribute :label, :string
attribute :value, :string
validates :label, :value, presence: true
end
Hi @jsice!
Thanks for the report, I'll do my best to investigate this issue later this week
Rolled out 0.4.1 with fixes for both issues @exsemt @jsice
Thanks!
Hey all, firstly this is a really cool gem and it will hopefully make my life way easier! I've just started playing around with it and have the following set up
class Pathogen < ActiveRecord::Base
attribute :configuration, Configuration.to_type
end
class Configuration
include StoreModel::Model
accepts_nested_attributes_for :susceptibility
attribute :susceptibility, Susceptibility.to_array_type
end
class Susceptibility
include StoreModel::Model
attribute :icon, :string
attribute :link, :string
attribute :name, :string
attribute :value, :string
attribute :render_method, :string
end
When I submit the update form on the pathogen my params look like
> pathogen_params[:configuration]
=> <ActionController::Parameters {"susceptibility_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {"value"=>"Edit one", "name"=>"General susceptibility", "icon"=>"", "link"=>"", "render_method"=>"string"} permitted: true>, "1"=><ActionController::Parameters {"value"=>"Edit two", "name"=>"Antibiogram footnotes", "icon"=>"", "link"=>"", "render_method"=>"string"} permitted: true>} permitted: true>} permitted: true>
but when I call update on the pathogen model it does not save the nested susceptibility attributes and instead returns just nil
> Pathogen.find(1898).configuration
Pathogen Load (1.2ms) SELECT "pathogens".* FROM "pathogens" WHERE "pathogens"."id" = $1 LIMIT $2 /*application:Spectrum*/ [["id", 1898], ["LIMIT", 1]]
=> #<Configuration susceptibility: nil, general_information: nil>
I'm thinking I am just doing something small wrong...any help would be greatly appreciated!
Hey @evanshabsove, I'm not sure it will help, but just in case, take a look here: https://github.com/DmitryTsepelev/store_model/issues/41
I didn't even know there is an accept_nested_attributes_for
support! Gotta play around with it :)
I ended up figuring it out! I was trying to be too cute with it. We use Inherited Resources (https://github.com/activeadmin/inherited_resources) and I was hoping the update! method in that would magically take care of everything, but I was wishing too hard. Changing the assignment to just
@pathogen.configuration = configuration_params[:configuration].to_hash
Fixed everything. @FunkyloverOne thanks for linking me to the issue thread!
Looking at this though I wonder if I just remove the :configuration part of the param I can be cute with it...anyways a discussion for another place.
I know this is an old issue, but I stumbled upon an error when using shoulda matchers:
Failure/Error: it { is_expected.to accept_nested_attributes_for(:parcels) }
NoMethodError:
undefined method `nested_attributes_options' for SomeModel:Class
# /usr/local/bundle/gems/shoulda-matchers-5.1.0/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb:196:in `model_config'
# /usr/local/bundle/gems/shoulda-matchers-5.1.0/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb:192:in `config'
# /usr/local/bundle/gems/shoulda-matchers-5.1.0/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb:152:in `exists?'
# /usr/local/bundle/gems/shoulda-matchers-5.1.0/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb:121:in `matches?'
This leads to this line https://github.com/thoughtbot/shoulda-matchers/blob/main/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb#L196
Is there something missing inside store model?
Right, this method was not ported 😞
Is there any chance, this method gets ported in the next release?
Sure, I just need a volounteer and will be happy to review the PR! 🙂
any updates?