Ruby on rails 设计公寓在设计用户创建时或之后创建租户

Ruby on rails 设计公寓在设计用户创建时或之后创建租户,ruby-on-rails,ruby,devise,apartment-gem,Ruby On Rails,Ruby,Devise,Apartment Gem,我有一个小应用程序,使用Desive和公寓宝石 我有一个拥有一个组织(租户名称)的用户(设计) 组织有一个:所有者、类名“用户” 我想使用设计登记表也创建租户和分配给管理员。 我想我已经读过很多关于Desive公寓/Desive定制控制器/Desive嵌套属性的教程,我自己都弄糊涂了 注册表格 app/views/design/registrations/new.html.erb <div class="row"> <div class="col-lg-4 col-md-6

我有一个小应用程序,使用Desive和公寓宝石

我有一个拥有一个组织(租户名称)的用户(设计)

组织有一个:所有者、类名“用户”

我想使用设计登记表也创建租户和分配给管理员。 我想我已经读过很多关于Desive公寓/Desive定制控制器/Desive嵌套属性的教程,我自己都弄糊涂了

注册表格 app/views/design/registrations/new.html.erb

<div class="row">
  <div class="col-lg-4 col-md-6 ml-auto mr-auto">
    <h1 class="text-center">Sign Up</h1>

    <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
      <%= render partial: 'devise/shared/error_messages', resource: resource %>

      <div class="form-group">
        <%= f.email_field :email, autofocus: false, class: 'form-control', placeholder: "Email Address" %>
      </div>
      <div class="form-group">
        <%= f.simple_fields_for :organizations do |o| %>
          <%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false  %>
        <% end %>
      </div>

      <div class="form-group">
        <%= f.password_field :password, autocomplete: "off", class: 'form-control', placeholder: 'Password' %>
      </div>

      <div class="form-group">
        <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password' %>
      </div>

      <div class="form-group">
        <%= f.submit "Sign up", class: "btn btn-primary btn-block btn-lg" %>
      </div>
    <% end %>

    <div class="text-center">
      <%= render "devise/shared/links" %>
    </div>
  </div>
</div>
并添加了定制的消毒剂

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  # GET /resource/sign_up
  # def new
  #   super
  # end

  # POST /resource
  def create
    super
  end

  # GET /resource/edit
  # def edit
  #   super
  # end

  # PUT /resource
  # def update
  #   super
  # end

  # DELETE /resource
  # def destroy
  #   super
  # end

  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  # def cancel
  #   super
  # end

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
   devise_parameter_sanitizer.permit(:sign_up, keys: [:email, organizations: [:name]])
  end

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_account_update_params
  #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
  # end

  # The path used after sign up.
  # def after_sign_up_path_for(resource)
  #   super(resource)
  # end

  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
end
当我完成注册过程时,我得到了用户的未知属性“organizations”

更新:

我添加了两个新的迁移来添加对组织上的用户的引用,以及对用户的组织

我这样做是为了为所有者创建关联,我应该调用引用所有者吗

class AddUserToOrganization < ActiveRecord::Migration[5.2]
  def change
    add_reference :organizations, :user, type: :uuid, null: false, index: true, foreign_key: true
  end
end

class AddOrganizationToUser < ActiveRecord::Migration[5.2]
  def change
    add_reference :users, :organization, type: :uuid, null: false, index: true, foreign_key: true
  end
end
我按照的指示将我的用户/注册控制器更改为:

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  def new
    super
    @organization = Organization.new
  end

  # POST /resource
  def create
    super
  end

  # GET /resource/edit
  # def edit
  #   super
  # end

  # PUT /resource
  # def update
  #   super
  # end

  # DELETE /resource
  # def destroy
  #   super
  # end

  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  # def cancel
  #   super
  # end

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
   devise_parameter_sanitizer.permit(:sign_up, keys: [:email, organizations: [:name]])
  end

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_account_update_params
  #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
  # end

  # The path used after sign up.
  # def after_sign_up_path_for(resource)
  #   super(resource)
  # end

  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
end
类用户::注册控制器<设计::注册控制器
在\u操作之前:配置\u注册\u参数,仅:[:创建]
#在\u操作之前:配置\u帐户\u更新\u参数,仅:[:更新]
def新
超级的
@organization=organization.new
结束
#员额/资源
def创建
超级的
结束
#获取/资源/编辑
#定义编辑
#超级
#结束
#投入/资源
#def更新
#超级
#结束
#删除/删除资源
#def销毁
#超级
#结束
#获取/资源/取消
#强制执行通常在签名后过期的会话数据
#现在就要到期了。如果用户愿意,这是有用的
在进程中间取消OAuthIn签入/注册,
#删除所有OAuth会话数据。
#def取消
#超级
#结束
#保护
#如果要允许使用额外的参数,请将它们附加到消毒液中。
def配置\注册\参数
设计参数消毒器。许可证(:注册,密钥:[:电子邮件,组织:[:名称]])
结束
#如果要允许使用额外的参数,请将它们附加到消毒液中。
#def配置\帐户\更新\参数
#设计\u参数\u消毒器。允许(:帐户\u更新,键:[:属性])
#结束
#注册后使用的路径。
#注册后的def路径(资源)
#超级(资源)
#结束
#注册非活动帐户后使用的路径。
#非活动后的def注册路径(资源)
#超级(资源)
#结束
结束
现在我的表格呢

<%= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-horizontal' }) do |f| %>
      <%= render partial: 'devise/shared/error_messages', resource: resource %>

        <%= f.input :email, autofocus: false, class: 'form-control', placeholder: "Email Address", label: false  %>
        <%= f.simple_fields_for :organization do |o| %>
          <%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false  %>
        <% end %>
        <%= f.input :password, autocomplete: "off", class: 'form-control', placeholder: 'Password', label: false  %>
        <%= f.input :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password', label: false  %>
        <%= f.button :submit, "Sign up", class: "btn btn-primary btn-block btn-lg" %>
    <% end %>
resource\u name,:url=>session\u路径(resource\u name),:html=>{:class=>'form horizontal'})do | f |%>

我现在的问题是在表单视图中看不到组织名称字段。

在has\u one关系中,您应该使用单数形式:

  <div class="form-group">
    <%= f.simple_fields_for :organization do |o| %>
      <%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false  %>
    <% end %>
  </div>

我认为您的代码的其余部分应该按原样工作

编辑:如何实例化新组织

您指出表单为空,这是因为没有组织实例。在用户控制器中执行以下操作:

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  GET /resource/sign_up
  def new
    super
    @user.organization = Organization.new
  end

  # POST /resource
  def create
    super
  end
end
类用户::注册控制器<设计::注册控制器
在\u操作之前:配置\u注册\u参数,仅:[:创建]
#在\u操作之前:配置\u帐户\u更新\u参数,仅:[:更新]
获取/资源/注册
def新
超级的
@user.organization=organization.new
结束
#员额/资源
def创建
超级的
结束
结束

当我将组织更改为组织时,它将从我的表单中删除…您应该实例化一个新组织。。。否则,您将无法在视图中看到一个。要么在控制器中执行,要么将实例化添加到简单的_字段调用中。请参阅我编辑的答案。非常感谢,但现在我在Users::RegistrationController#new无法写入未知属性
user\u id
中获得了ActiveModel::MissingAttributeError。这可能是因为我使用的是UUID吗?架构正在更新中?我不知道你指的是什么?我没有得到一个错误,因为我甚至看不到表单中的组织,这是我实施更改后的问题。我认为问题是因为我说组织有一个:所有者,类名:'用户'。。。我是否在模式中错误地引用了它?
ActiveRecord::Schema.define(version: 2019_05_13_223120) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "pgcrypto"
  enable_extension "plpgsql"
  enable_extension "uuid-ossp"

  create_table "Organizations_Users", id: false, force: :cascade do |t|
    t.uuid "Organization_id", null: false
    t.uuid "User_id", null: false
  end

  create_table "clients", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "name"
    t.uuid "organization_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["organization_id"], name: "index_clients_on_organization_id"
  end

  create_table "equipment", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "name"
    t.uuid "site_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["site_id"], name: "index_equipment_on_site_id"
  end

  create_table "organizations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.uuid "user_id", null: false
    t.index ["user_id"], name: "index_organizations_on_user_id"
  end

  create_table "sites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "name"
    t.uuid "client_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["client_id"], name: "index_sites_on_client_id"
  end

  create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.uuid "organization_id", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["organization_id"], name: "index_users_on_organization_id"
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

  add_foreign_key "clients", "organizations"
  add_foreign_key "equipment", "sites"
  add_foreign_key "organizations", "users"
  add_foreign_key "sites", "clients"
  add_foreign_key "users", "organizations"
end
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  def new
    super
    @organization = Organization.new
  end

  # POST /resource
  def create
    super
  end

  # GET /resource/edit
  # def edit
  #   super
  # end

  # PUT /resource
  # def update
  #   super
  # end

  # DELETE /resource
  # def destroy
  #   super
  # end

  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  # def cancel
  #   super
  # end

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
   devise_parameter_sanitizer.permit(:sign_up, keys: [:email, organizations: [:name]])
  end

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_account_update_params
  #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
  # end

  # The path used after sign up.
  # def after_sign_up_path_for(resource)
  #   super(resource)
  # end

  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
end
<%= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-horizontal' }) do |f| %>
      <%= render partial: 'devise/shared/error_messages', resource: resource %>

        <%= f.input :email, autofocus: false, class: 'form-control', placeholder: "Email Address", label: false  %>
        <%= f.simple_fields_for :organization do |o| %>
          <%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false  %>
        <% end %>
        <%= f.input :password, autocomplete: "off", class: 'form-control', placeholder: 'Password', label: false  %>
        <%= f.input :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password', label: false  %>
        <%= f.button :submit, "Sign up", class: "btn btn-primary btn-block btn-lg" %>
    <% end %>
  <div class="form-group">
    <%= f.simple_fields_for :organization do |o| %>
      <%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false  %>
    <% end %>
  </div>
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  GET /resource/sign_up
  def new
    super
    @user.organization = Organization.new
  end

  # POST /resource
  def create
    super
  end
end