Each user in the application has a profile that has to be filled out by the user when registering. The user and profile classes are as follows:
user.rb:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable
has_one :profile
end
profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
end
the view form:
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= f.input :email, required: true, autofocus: true
= f.simple_fields_for :profile do |pf|
= pf.input :name
= pf.input :bio
= f.input :password, required: true
= f.input :password_confirmation, required: true
= f.button :submit
The problem is that the profile object needs to be initialized before the form is rendered.
I decided to override the new
method of the Devise::RegistrationsController
:
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
def new
build_resource({}) # copied from super
resource.build_profile # my custom initialization code
respond_with self.resource # copied from super
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << { profile_attributes: [:name, :bio] }
end
end
This doesn't seem to be very DRY since I am duplicating the code in the super new method. I might also break things if the super controller method new
changes when the gem is upgraded. Any better way to override the resource (user) creation without duplicating code?