Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Attributes? #13

Open
exsemt opened this issue Jul 12, 2019 · 22 comments
Open

Nested Attributes? #13

exsemt opened this issue Jul 12, 2019 · 22 comments

Comments

@exsemt
Copy link

exsemt commented Jul 12, 2019

Hi @DmitryTsepelev,

are you planning to add the accept_nested_attributes_for function to the store_model?

@DmitryTsepelev
Copy link
Owner

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?

@exsemt
Copy link
Author

exsemt commented Jul 12, 2019

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=

@DmitryTsepelev
Copy link
Owner

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

@DmitryTsepelev
Copy link
Owner

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?

@exsemt
Copy link
Author

exsemt commented Jul 24, 2019

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 }])

@DmitryTsepelev
Copy link
Owner

Here we go #17 - could you please try it out before I merge it in?

@DmitryTsepelev
Copy link
Owner

Released 0.4.0 with accept_nested_attributes_for support

@exsemt
Copy link
Author

exsemt commented Jul 29, 2019

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" }}])

@DmitryTsepelev
Copy link
Owner

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" }}]?

@exsemt
Copy link
Author

exsemt commented Jul 29, 2019

Thx! Works! 👍

@jsice
Copy link

jsice commented Jul 29, 2019

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

@DmitryTsepelev
Copy link
Owner

Hi @jsice!

Thanks for the report, I'll do my best to investigate this issue later this week

@DmitryTsepelev
Copy link
Owner

Rolled out 0.4.1 with fixes for both issues @exsemt @jsice

@jsice
Copy link

jsice commented Jul 31, 2019

Thanks!

@evanshabsove
Copy link

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!

@flvrone
Copy link

flvrone commented Dec 5, 2019

Hey @evanshabsove, I'm not sure it will help, but just in case, take a look here: #41

I didn't even know there is an accept_nested_attributes_for support! Gotta play around with it :)

@evanshabsove
Copy link

evanshabsove commented Dec 5, 2019

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.

@23tux
Copy link

23tux commented Apr 21, 2022

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?

@DmitryTsepelev
Copy link
Owner

Right, this method was not ported 😞

@23tux
Copy link

23tux commented Jun 9, 2022

Is there any chance, this method gets ported in the next release?

@DmitryTsepelev
Copy link
Owner

Sure, I just need a volounteer and will be happy to review the PR! 🙂

@alexandreh92
Copy link

any updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants