Devise: Ability to pass parameters to the registra

2019-05-06 17:27发布

问题:

Once in a while we send customized registration links to our leads. The link contains parameters than can be used to pre-fill the registration form.

http://www.example.com/users/sign_up?user[company_name]=Foo&user[region]=NA

Our registration form has fields for accepting company name and region. Which can be pre-filled based on the registration link.

This should work in practice, but it doesn't due to how the registrations#new action is implemented. The new action calls the build_resource method with an empty hash.

def new
  resource = build_resource({})
  respond_with resource
end

The build_resource method ignores the resource_params when the input is non nil.

def build_resource(hash=nil)
  hash ||= resource_params || {}
  self.resource = resource_class.new_with_session(hash, session)
end  

I had to over-ride the the new action in my registrations controller to overcome this issue. I don't like my solution as it is brittle.

def new
  resource = build_resource
  respond_with resource
end

Is there a reason why the new action is invoked with an empty hash? Can it be invoked with out empty hash(like in the create action)?

回答1:

I ended up overriding build_resource and scoping the change to new action.

def build_resource(hash=nil)
  # scope the change to new actions 
  return super unless action_name == "new"
  super.tap do |user|
    user.company_name = params[:user][:company_name]
    user.reg‭ion = params[:user][:reg‭ion]      
  end
end


回答2:

I believe this is the intended behaviour of the build_resource method. Similar to Model.new you can either pass a hash of initializing properties or nothing, resulting in a pre-filled and an empty model respectively.

If you want to make your controller action more explicit you could instead call build_resource(params[:user]) which should avoid the brittleness you're concerned about.