加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 如何在Rails中的注册表单中创建Devise用户时创

发布时间:2020-12-17 04:00:58 所属栏目:百科 来源:网络整理
导读:我的系统中有不同类型的用户.一种是,比方说,设计师: class Designer ActiveRecord::Base attr_accessible :user_id,:portfolio_id,:some_designer_specific_field belongs_to :user belongs_to :portfolioend 这是在用户注册时立即创建的.因此,当用户填写si
我的系统中有不同类型的用户.一种是,比方说,设计师:

class Designer < ActiveRecord::Base
  attr_accessible :user_id,:portfolio_id,:some_designer_specific_field
  belongs_to :user
  belongs_to :portfolio
end

这是在用户注册时立即创建的.因此,当用户填写sign_up表单时,将创建一个Devise用户以及此Designer对象,并将其user_id设置为创建的新用户.如果我可以访问控制器的代码,这很容易.但是对于Devise,我无法访问此注册控制器.

注册后创建用户和设计师的正确方法是什么?

解决方法

在最近的一个项目中,我使用 form object pattern一步创建了Devise用户和公司.这涉及绕过Devise的RegistrationsController并创建自己的SignupsController.

# config/routes.rb
# Signups
get 'signup' => 'signups#new',as: :new_signup
post 'signup' => 'signups#create',as: :signups  


# app/controllers/signups_controller.rb
class SignupsController < ApplicationController
  def new
    @signup = Signup.new
  end

  def create
    @signup = Signup.new(params[:signup])

    if @signup.save
      sign_in @signup.user
      redirect_to projects_path,notice: 'You signed up successfully.'
    else
      render action: :new
    end
  end
end

引用的注册模型被定义为表单对象.

# app/models/signup.rb

# The signup class is a form object class that helps with
# creating a user,account and project all in one step and form
class Signup
  # Available in Rails 4
  include ActiveModel::Model

  attr_reader :user
  attr_reader :account
  attr_reader :membership

  attr_accessor :name
  attr_accessor :company_name
  attr_accessor :email
  attr_accessor :password

  validates :name,:company_name,:email,:password,presence: true

  def save
    # Validate signup object
    return false unless valid?

    delegate_attributes_for_user
    delegate_attributes_for_account

    delegate_errors_for_user unless @user.valid?
    delegate_errors_for_account unless @account.valid?

    # Have any errors been added by validating user and account?
    if !errors.any?
      persist!
      true
    else
      false
    end
  end

  private

  def delegate_attributes_for_user
    @user = User.new do |user|
      user.name = name
      user.email = email
      user.password = password
      user.password_confirmation = password
    end
  end

  def delegate_attributes_for_account
    @account = Account.new do |account|
      account.name = company_name
    end
  end

  def delegate_errors_for_user
    errors.add(:name,@user.errors[:name].first) if @user.errors[:name].present?
    errors.add(:email,@user.errors[:email].first) if @user.errors[:email].present?
    errors.add(:password,@user.errors[:password].first) if @user.errors[:password].present?
  end

  def delegate_errors_for_account
    errors.add(:company_name,@account.errors[:name].first) if @account.errors[:name].present?
  end

  def persist!
    @user.save!
    @account.save!
    create_admin_membership
  end

  def create_admin_membership
    @membership = Membership.create! do |membership|
      membership.user = @user
      membership.account = @account
      membership.admin = true
    end
  end
end

关于表单对象(以及我的工作源)的优秀读物是this CodeClimate blog post on Refactoring.

总之,我更喜欢这种方法而不是使用accepts_nested_attributes_for,尽管可能有更多的方法.如果你找到一个,请告诉我!

===

编辑:添加引用的模型及其关联以便更好地理解.

class User < ActiveRecord::Base
  # Memberships and accounts
  has_many :memberships
  has_many :accounts,through: :memberships
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :account
end

class Account < ActiveRecord::Base
  # Memberships and members
  has_many :memberships,dependent: :destroy
  has_many :users,through: :memberships
  has_many :admins,through: :memberships,source: :user,conditions: { 'memberships.admin' => true }
  has_many :non_admins,conditions: { 'memberships.admin' => false }
end

模型中的这个结构与saucy一起建模,这是一个思想机器人的宝石.源不在Github AFAIK上,但可以从gem中提取它.我通过重塑它已经学到了很多东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读