设计帐户类型的嵌套表单

时间:2018-04-15 00:08:06

标签: ruby-on-rails ruby devise nested-forms

我设置了Devise来创建帐户,它们链接到商家人员。我在您注册新帐户时试图找到一种方法来包含人员信息和业务信息。有没有办法扩展新的注册表格?我还希望它根据哪个单选按钮处于活动状态而更改(默认情况下为Personnel)。我认为嵌套表格是要走的路,但说实话,我不知道如何去做。

商业模式和人员模型都有这一行......

app / models / Business.rb&应用程序/模型/ Personnel.rb

has_one :account, as :accountable

并且帐户模型看起来像这样......

应用/模型/ Account.rb

class Account < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :accountable, polymorphic: true

  ACCOUNT_TYPES=["SuperAccount","Chamber","Personnel", "Business"]
  attr_accessor :type
end

以下是我如何设置注册控制器以防万一。

应用/控制器/ registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
  def new
    super
  end

  def create
    build_resource(sign_up_params)
    if (resource.type=="Personnel")
      resource.accountable = Personnel.new
      SignupNotifierMailer.personnel(@account).deliver
    elsif(resource.type =="Business")
      resource.accountable = Business.new
      SignupNotifierMailer.business(@account).deliver
    end
    resource.save
    yield resource if block_given?
    if resource.persisted?
      if resource.active_for_authentication?
        set_flash_message! :notice, :signed_up
        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}"
        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

  def destroy
    @account.accountable.destroy!
    super
  end

  protected

    def after_sign_up_path_for(resource)
      if (resource.type == 'Personnel')
        edit_personnel_path(current_account.accountable_id)
      elsif (resource.type == 'Business')
        edit_business_path(current_account.accountable_id)
      else
        super
      end
    end
end

最后,我想改变观点。

app / views / devise / registrations / new.html.erb

<h2>Sign Up</h2>

<%= simple_nested_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :email, required: true, autofocus: true %>
    <%= f.input :password, required: true, hint: ("#{@minimum_password_length} 
        characters minimum" if @minimum_password_length) %>
    <%= f.input :password_confirmation, required: true %>
    <%= f.input :type, required: true, as: :radio_buttons, label: "Type of Account", 
            collection: Account::ACCOUNT_TYPES.drop(2), checked: 'Personnel' %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, "Sign Up" %>
  </div>
<% end %>

1 个答案:

答案 0 :(得分:0)

您应该在帐户模型中使用accepts_nested_attributes_for :accountable,然后您应该可以将这些内容传递给build_resource

在HTML表单中,您应该使用嵌套表单,该表单将生成表单字段名称,如account[accountable][name]=Foobar,并将传递给您的模型。您可能需要包含accountable_type密钥,并确保它在控制器中可接受的选项范围内。

有关Devise自述文件的一些信息,介绍了如何使用强参数在控制器中过滤这些参数。

https://github.com/plataformatec/devise#strong-parameters