Search code examples
inheritanceruby-on-rails-4mongoidnested-attributesstrong-parameters

Rails4 Mongoid inheritance + Strong Paramters +Nested attributes


I have the following code skeleton where a Column embeds_many Contents of types Image and Map:

class Column
  include Mongoid::Document

  embeds_many: contents
  accepts_nested_attributes_for :contents, allow_destroy: true
end

class content
  include Mongoid::Document

  field :description
end

class Image < Content
  field :src, type: String
end

class Map < Content      
  field :latitude, type: String
  field :longitude, type: String
end

Now I want to pass a JSON from my Angular view to the columns_controller to create a column with two contents; image and map.

I attempted passing the following hash:

{'column' => 'contents_attributes' => [{_type: 'Image', description: 'image description', src: 'path/to/image'}, {_type: 'Map', description: 'map description', latitude: '25.3321', longitude: '35.32423'}]}

the column_params method is:

def column_params
  params.require(:column).permit(:_id, contents_attributes: [:_id, _type, :description, :src, :latitude, :longitude]) 
end

The above raised the following error:

Attempted to set a value for '_type' which is not allowed on the model Content.


Solution

  • as a workaround in the mongoid gem (version 4.0.0) in the file lib/mongoid/relations/builders/nested_attributes/many.rb I changed the creation of the object in the method process_attributes at line 109 to be

    klass = attrs[:_type].try(:constantize) || metadata.klass
    existing.push(Factory.build(klass, attrs)) unless destroyable?(attrs)
    

    instead of

    existing.push(Factory.build(metadata.klass, attrs)) unless destroyable?(attrs)
    

    and this solved my problem.