Rails 4 Not Updating Nested Attributes Via JSON

前端 未结 3 1850
囚心锁ツ
囚心锁ツ 2021-01-04 09:23

I\'ve scoured related questions and still have a problem updating nested attributes in rails 4 through JSON returned from my AngularJS front-end.

Question:

相关标签:
3条回答
  • 2021-01-04 09:44

    You can also monkey patch parameter wrapping to always include nested_attributes by putting this into eg wrap_parameters.rb initializer:

        module ActionController
            module ParamsWrapper
    
                Options.class_eval do
                    def include
                        return super if @include_set
    
                        m = model
                        synchronize do
                            return super if @include_set
                            @include_set = true
                            unless super || exclude
                                if m.respond_to?(:attribute_names) && m.attribute_names.any?
                                    self.include = m.attribute_names + nested_attributes_names_array_of(m)
                                end
                            end
                        end
                    end
    
                    private 
                        # added method. by default code was equivalent to this equaling to []
                        def nested_attributes_names_array_of model
                            model.nested_attributes_options.keys.map { |nested_attribute_name| 
                                nested_attribute_name.to_s + '_attributes' 
                            }
                        end
                end
    
            end
        end
    
    0 讨论(0)
  • 2021-01-04 09:56

    I've also been working with a JSON API between Rails and AngularJS. I used the same solution as RTPnomad, but found a way to not have to hardcode the include attributes:

    class CandidatesController < ApplicationController
      respond_to :json
    
      nested_attributes_names = Candidate.nested_attributes_options.keys.map do |key| 
        key.to_s.concat('_attributes').to_sym
      end
    
      wrap_parameters include: Candidate.attribute_names + nested_attributes_names,
        format: :json
    
      # ...
    end
    

    Refer to this issue in Rails to see if/when they fix this problem.

    Update 10/17
    Pending a PR merge here: rails/rails#19254.

    0 讨论(0)
  • 2021-01-04 09:58

    I figured out one way to resolve my issue based on the rails documentation at: http://edgeapi.rubyonrails.org/classes/ActionController/ParamsWrapper.html

    Basically, Rails ParamsWrapper is enabled by default to wrap JSON from the front-end with a root element for consumption in Rails since AngularJS does not return data in a root wrapped element. The above documentation contains the following:

    "On ActiveRecord models with no :include or :exclude option set, it will only wrap the parameters returned by the class method attribute_names."

    Which means that I must explicitly include nested attributes with the following statement to ensure Rails includes all of the elements:

    class CandidatesController < ApplicationController
    
        before_filter :authenticate_user!
        respond_to :json
        wrap_parameters include: [:id, :nickname, :works_attributes]
        ...
    

    Please add another answer to this question if there is a better way to pass JSON data between AngularJS and Rails

    0 讨论(0)
提交回复
热议问题