Rails4:如何访问Devise Registrations Controller的内容

Rails 4: how to access the content of Devise Registrations Controller

我有一个 Rails 4 应用程序使用 Devise 进行身份验证 — 它目前正在运行。

我现在正在关注这个关于 Creating a Scoped Invitation System for Rails.

的 coderwall 教程

新邀请用户注册部分,作者建议更新RegistrationsController,如下:

def new
   @token = params[:invite_token] #<-- pulls the value from the url query string
end

def create
  @newUser = build_user(user_params)
  @newUser.save
  @token = params[:invite_token]
  if @token != nil
     org =  Invite.find_by_token(@token).user_group #find the user group attached to the invite
     @newUser.user_groups.push(org) #add this user to the new user group as a member
  else
    # do normal registration things #
  end
end

在 Stack Overflow 和网络上有很多问题和答案,解释了如何覆盖 Devise RegistrationsControllers,包括:

所以,我知道创建一个继承自 Devise::RegistrationsControllerMyDevise::RegistrationController 并在我要修改的操作开始时调用 super 命令将保留原始功能这些操作。

我可能会做类似的事情:

def new
  super
  @token = params[:invite_token] #<-- pulls the value from the url query string
end

def create
  @newUser = build_user(user_params)
  @newUser.save
  @token = params[:invite_token]
  if @token != nil
    org =  Invite.find_by_token(@token).user_group #find the user group attached to the invite
    @newUser.user_groups.push(org) #add this user to the new user group as a member
  else
    super
  end
end

我唯一担心的是,在不知道这个控制器和那些动作的原始内容的情况下,我不喜欢覆盖控制器和它的动作。

——————

更新:我知道我们可以从 Devise GitHub repository 访问 Devise::RegistrationsController,但我不确定我的是否仍然一样。例如,当我实施我的身份验证系统时,它可能已被修改。

——————

更新 2:如果我在第一次更新中使用 Devise::RegistrationsController 中提到的代码,我可以为我的新 RegistrationsController:

def new
  @token = params[:invite_token] #<-- pulls the value from the url query string
  build_resource({})
  set_minimum_password_length
  yield resource if block_given?
  respond_with self.resource
end

def create
  build_resource(sign_up_params)
  resource.save
  @token = params[:invite_token]
  if @token != nil
     org =  Invite.find_by_token(@token).calendar #find the calendar attached to the invite
     resource.calendars.push(org) #add this user to the new calendar as a member
  else
    yield resource if block_given?
    if resource.persisted?
      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
      clean_up_passwords resource
      set_minimum_password_length
      respond_with resource
    end
  end
end

这有意义吗?

——————

那么,有没有办法从应用程序的某处提取我当前 Devise::RegistrationsController 的内容?

如果没有,我正在考虑实施的代码是否有意义?

您可以使用:

bundle open devise # bundle will open devise folder in your editor

关于您的代码:

有一个更简洁的解决方案。看看这段代码:

def new
  build_resource({})
  set_minimum_password_length
  yield resource if block_given?
  respond_with self.resource
end

这几乎是自然的英语,只有 yield resource if block_given? 行可能会让您感到困惑。该行执行以下操作:如果使用块调用方法 new,则将 resource 变量传递给该块并执行它。这样做特别是为了简化自定义行为的添加和覆盖。

所以,我们可以覆盖这段代码如下:

def new
  # here you don't need this `resource` variable, but somebody may need it
  super do |resource| 
    @token = params[:invite_token]
  end
end

这和你写的完全一样

def new
  build_resource({})
  set_minimum_password_length
  @token = params[:invite_token]
  respond_with self.resource
end

编辑 2:试试这个:

def create
  super do |resource|
    @token = params[:invite_token]
    if @token != nil
      org = Invite.find_by_token(@token).calendar #find the calendar attached to the invite
      resource.calendars.push(org) #add this user to the new calendar as a member
    end
  end
end        

如果您想查看您使用的是哪个版本的 Devise 运行,请在终端中执行此命令:gem which devise。这样您就可以根据您使用的版本在 GitHub 上检查正确的源代码。