Rails / Devise自定义create方法

时间:2014-08-09 23:02:18

标签: ruby-on-rails ruby devise

我生成一个特殊代码,该代码对每个用户都是唯一的,并在注册/创建时生成。我想将它存储在创建数据库中。

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_permitted_parameters

  def create
    # insert special code into instance and ensure that code is unique in database
    super # continue to devise registration to CREATE user
  end

  protected
  def special_code
    ( (0...8).map { char = (65 + rand(26)).chr; }[0..rand(2...4)] << rand(1..9) ).join.downcase
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << [:name, :gender, :birthday]
  end
end 

从我的代码中可以看到,我添加了:name,:gender,:birthday columns(这样可以正常工作)。我只是不知道如何将special_code放入记录中。请指教。谢谢!

2 个答案:

答案 0 :(得分:0)

我是按照以下方式完成的(根据您的情况调整自己的代码):

应用/控制器/关切/ user_resource.rb

module UserResource
  extend ActiveSupport::Concern
  include Resource

  included do
    def resource_name
      :user
    end

    def resource
      if user_signed_in?
        current_user
      else
        @resource || User.new
      end
    end

    def build_resource(hash=nil)
      custom_params = hash.present? ? hash : {}
      custom_params[:special_code] = special_code
      self.resource = resource_class.new_with_session(custom_params || {}, session)
    end

    def devise_mapping
      @devise_mapping ||= Devise.mappings[:user]
    end

    helper_method :resource_name
    helper_method :resource
    helper_method :devise_mapping

    protected

    def special_code
      ( (0...8).map { char = (65 + rand(26)).chr; }[0..rand(2...4)] << rand(1..9) ).join.downcase
    end
  end
end

您的特殊代码可能属于UserResource类。

应用/控制器/关切/ resource.rb

module Resource
  extend ActiveSupport::Concern

  included do
    before_action { |c| c.resource}

    def resource_name
      raise NotImplementedError
    end

    def resource
      raise NotImplementedError
    end

    def devise_mapping
      raise NotImplementedError
    end
  end
end

应用/控制器/用户/ registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
  include UserResource

  def create
    resource = build_resource(sign_up_params)
    yield resource if block_given?
    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_flashing_format?
        sign_up(resource_name, resource)
        respond_with resource, location: after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    else
      flash[:error] = "Sorry, we could not save you in our database. Please contact an adminstrator. #{resource.inspect}"
      clean_up_passwords resource
      respond_with resource
    end
  end

end

路线应如下所示。看来你已经做到了。

应用/配置/ routes.rb中

devise_for :users, :controllers => {
  registrations: 'users/registrations'
}

因为当我尝试使用更短的解决方案时代码不起作用,我不得不复制some code from the original Devise module。不要问我为什么我以前的代码不起作用,这真的很奇怪而且难以修复。

答案 1 :(得分:0)

您需要修改create方法。首先找到用户在create中分配的内容(可能是资源),然后为其分配特殊代码

  def create
    # insert special code into instance and ensure that code is unique in database
    super # continue to devise registration to CREATE user
    resource.update special_code: special_code # may want to check model is still valid at this point and handle errors if not
  end

也在路线中,您需要告诉它使用此控制器

 devise_for :users, :controllers => { :registrations => 'users/registrations' }