首页 > 解决方案 > Rails Devise - 创建用户并更新相关记录

问题描述

红宝石版本:2.6.3

导轨版本:6.0

我有 2 个模型

1) 用户

has_one :address, dependent: :destroy
accept_nested_attributes :address

2) 地址

belongs_to :user, optional: true

我将设计用于用户模型。地址模型已经有一些记录,但它们与用户没有关联。当用户来注册时,我必须显示与任何用户无关的可用地址列表。

我想在这种情况下使用嵌套形式。我覆盖了设计注册控制器,但参数中的属性不正确。

这是我的注册表代码

  <%= f.fields_for :address do |sc| %>
    <%= sc.label :address %>
    <%= sc.select :address, options_for_select(Address.available_addresses&.map{ |i| [i.address, i.id] }), class: 'form-control' %>
  <% end %>

参数

Parameters: {"authenticity_token"=>"MN6zE3Z7B7zhQupa6kvbqGN4kmc8pAHRrdqtKipDclki3f6H5M919YCe9O7b+M8X49wuD3UczzpRJDl0Fmx0SQ==", "user"=>{"first"=>"daa", "last"=>"dasa", "email"=>"aa@g.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "address_attributes"=>{"address"=>"1"}, "commit"=>"Sign up"}

application_controller.rb

before_action :configure_permitted_parameters, if: :devise_controller?

def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first, :last, address_attributes: [:id, :address]] )
  end

最主要的是它没有作为属性传递。它仅作为 传递address: [:address] 。如果我写f.fields_for :address它不会显示在视图中。但如果我写fields_for :address的不仅仅是它以形式显示。很奇怪为什么它没有按预期工作。

我不必创建新的地址记录。如何将现有记录与用户相关联?

更新

当我使用地址属性时,它只是为地址创建一条新记录,而不是为用户更新地址记录。我很奇怪为什么它不更新记录并插入新记录。我只是想更新地址记录的用户 ID。我不想创建地址模型的新记录。

更新 我用下面的代码解决了我的问题

new.html.erb

  <%= fields_for :address do |sc| %>
    <%= sc.label :address %>
    <%= sc.select :address, options_for_select(Address.available_addresses&.map{ |i| [i.address, i.id] }), class: 'form-control' %>
  <% end %>

users/registrations_controller.rb
if resource.persisted?
  if resource.active_for_authentication?
     address = Address.find(params[:address][:address])
     address.update_column(:user_id, resource.id)

我真的很想知道为什么会这样,我使用了嵌套属性,但它只是创建新记录而不是创建新用户和更新地址。这是一个非常小的问题,我想弄清楚幕后发生了什么。

标签: ruby-on-railsdevise

解决方案


您需要生成设计控制器并配置registrations_controller.rb 配置设计控制器 ,因为您需要在创建新用户后构建地址。

rails g devise:controllers users -c=registrations

并将控制器添加到 devise_for 路由中:例如: devise_for :users, controllers: { registrations: 'users/registrations' }

然后您可以编辑 sign_up_params 以包含address_parameters

def sign_up_params
  params.require(:user).permit(:first, :last, address_attributes: [:your_address_attributes])
end

您还需要覆盖newregistrations_controller包括构建地址

def new
  super { resource.build_address }
end

要知道这是如何工作的,你需要看看registerations_controller

对于视图部分,您仍然需要f.fields_for :address

希望这可以帮助。


推荐阅读