title: Rails 4/Devise/MongoDB: "Unpermitted parameters" using custom properties and strong parameters
body: <p>Trying to add a nested custom attribute, <strong>Profile</strong> (a Mongoid document), to my devise <strong>User</strong> class. When the Devise registration form is submitted, it should create both a <strong>User</strong> and a corresponding <strong>Profile</strong> object as well.</p>
  
  <p>I'd like the end-result to look something like this in my MongoDB:</p>
  
  <p><strong>User:</strong></p>
  
  <pre><code>{
    # Devise fields:
    "email": "my@email.com",
    ...
    # Custom field
    "profile" : "&lt;object_id&gt;"
  }
  </code></pre>
  
  <p><strong>Profile:</strong></p>
  
  <pre><code>{
    "first_name": "Dave",
    ....
  }
  </code></pre>
  
  <hr>
  
  <p>Unfortunately, I am receiving this in my console whenever I submit my registration. It successfully creates a User but fails to create an associated Profile.</p>
  
  <pre><code>Started POST "/" for 127.0.0.1 at 2013-04-20 23:37:10 -0400
  Processing by Users::RegistrationsController#create as HTML
  Parameters:
     {"utf8"=&gt;"✓",
     "authenticity_token"=&gt;"awN2GU8EYEfisU0",
     "user"=&gt;
         {"profile_attributes"=&gt;
             {"first_name"=&gt;"Dave",
             "birthday(2i)"=&gt;"4",
             "birthday(3i)"=&gt;"21",
             "birthday(1i)"=&gt;"1933",
             "occupation_title"=&gt;"Software Developer"},
          "password"=&gt;"[FILTERED]",
          "password_confirmation"=&gt;"[FILTERED]",
          "email"=&gt;"my@email.com"}}
  Unpermitted parameters: profile_attributes
  </code></pre>
  
  <hr>
  
  <p>I have setup:</p>
  
  <ul>
  <li>Rails 4.0.0beta1, Ruby 2.0.0-p0</li>
  <li>Devise ('rails4' branch), Mongoid (from git)</li>
  <li>A custom Devise registrations controller to add a definition for strong parameters.</li>
  </ul>
  
  <p><strong>models/user.rb:</strong></p>
  
  <pre><code>class User
    include Mongoid::Document
  
    devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable,
       :token_authenticatable, :confirmable, :lockable, :timeoutable
  
    field :email,              type: String, default: ''
  
    ...
  
    has_one :profile
    accepts_nested_attributes_for :profile
  end
  </code></pre>
  
  <p><strong>models/profile.rb:</strong></p>
  
  <pre><code>class Profile
    include Mongoid::Document
    include Mongoid::Timestamps
  
    # Attributes
    # ----------
    field :slug,                type: String, default: '' # Acts as user-'friendlier' slug
    field :birthday,            type: DateTime, default: DateTime.now
    field :first_name,          type: String, default: ''
    field :occupation_title,    type: String, default: ''
  
    belongs_to :user
    embeds_many :photos
    has_one :occupation_industry, :as =&gt; :industry
  end
  </code></pre>
  
  <p><strong>controllers/users/registrations_controller.rb</strong></p>
  
  <pre><code>class Users::RegistrationsController &lt; Devise::RegistrationsController
  
    def resource_params
      params.require(:user).permit(:email, :password, :password_confirmation, :profile_attributes)
    end
    private :resource_params
  end
  </code></pre>
  
  <p><strong>routes.rb</strong></p>
  
  <pre><code>devise_for  :users,
                :path =&gt; '',
                :path_names =&gt; {
                  :sign_in =&gt; 'login',
                  :sign_out =&gt; 'logout',
                  :sign_up =&gt; 'register'
                  },
                :controllers =&gt; {
                  :registrations =&gt; "users/registrations",
                  :passwords =&gt; "users/passwords"
                }
  </code></pre>
  
  <p>I have already looked at these related posts, they didn't seem to help:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/15919761/rails-4-nested-attributes-unpermitted-parameters">Rails 4 Nested Attributes Unpermitted Parameters</a></li>
  <li><a href="https://gist.github.com/kazpsp/3350730" rel="nofollow noreferrer">https://gist.github.com/kazpsp/3350730</a></li>
  </ul>
  
  <hr>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Looks like Devise does actually support strong parameters in its 'rails4' branch (which is supposed to be merged into master in a few days.) Looking through the code, it appears you can override a params function for each action on devise controllers. For creating new users, its <code>sign_up_params</code> instead of <code>resource_params</code> in my example.</p>
  
  <p>Despite changing this name to the proper one, it still didn't work... only whitelisting all parameters using this bang seemed to work:</p>
  
  <pre><code>def sign_up_params
    params.require(:user).permit!
  end
  </code></pre>
  
  <p>Obviously, this kind of defeats the purpose of strong parameters... so now the question is how do I permit my nested attributes <code>profile_attributes</code> (as seen in my original question)?</p>