【问题标题】:Overriding Devise Parameters覆盖设计参数
【发布时间】:2023-03-26 11:47:02
【问题描述】:

我正在构建一个应用程序,它将管理员和公司置于一种形式中并将两者连接起来。连接部分设置了belongs_to关系(管理员属于公司)。

我遇到的问题是我正在使用 Devise,它会自动获取我的所有参数并尝试创建用户。问题是,在参数中,公司只是一个名称字符串。所以我需要建立公司,然后(大概)将 company_id 发送给 Devise,或者之后自己设置。

这是我在 Admin:RegistrationController 中尝试过的。

def create
  @company = Company.create(name: params[:admin][:company])
  super
  @admin.company = @company
end

创建管理员失败,Devise 返回错误“公司必须存在”。而且显然也很老套(或者至少感觉是这样)。

我应该在这里做什么,最佳做法是什么?谢谢!

【问题讨论】:

  • 我会考虑使用accepts_nested_attributes_for :company

标签: ruby-on-rails activerecord devise


【解决方案1】:

您可以覆盖#build_resource 以挂钩original #create implementation

class Admin:RegistrationController < ::Devise::RegistrationsController
  def build_resource(hash = {})
    super
    if action_name == "create"
      self.resource.company ||= Company.create 
    end
  end
end

但是从用户体验的角度来看,让用户通过 select 选择现有公司或使用 accepts_nested_attributes 让用户填写公司的字段可能会更好。

您也可以将关联设为可选,让用户在注册后填写公司详细信息。

最佳做法是什么?

无论哪种方式都能按时完成要求。

【讨论】:

    【解决方案2】:

    在文件夹 app/controllers/admins/registration_controller.rb 中创建覆盖一个新文件 并在下面添加此命令(某些部分是设计标准命令)

    class Admins::RegistrationsController < Devise::RegistrationsController
    
      def create
        build_resource(sign_up_params)
        @company = Company.create(name: params[:admin][:company])
        # resource is standard
        resource.company   = @company
        resource.save
      end
    
    end
    

    【讨论】:

    • 你可以在不复制粘贴整个实现的情况下做到这一点。
    • 这个实际上完全符合我的要求......虽然它似乎覆盖了登录阶段......有没有一种简单的方法让它在完成后登录?
    • 我找到了,只是一种设计方法,sign_in :admin, resource
    • 在编辑后仍然会破坏整个实现。如果有什么比原来的更糟糕的话。不要这样做。
    • 嗨,麦克斯 - 你能解释一下什么这么糟糕吗?看起来您正在使用一种设计方法 - build_resource - 然后在制作完成后添加公司......这里发生了什么可怕的事情?干杯...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    相关资源
    最近更新 更多