Как создать запись в ассоциации polymorphi c с несколькими типами пользователей - PullRequest
0 голосов
/ 12 марта 2020

У меня есть polimorphi c ассоциаций для нескольких типов пользователей, admin и original_user.

Мне нужно создать регистрацию пользователя со всеми атрибутами связанных моделей, но я могу создать только идентификатор записи в связанной таблице, например, Admin или OriginalUser.

Как я могу сделать это, если у меня есть вложенные атрибуты?

При отладке моего кода в терминале я увидел:

Unpermitted parameter: :admin_attributes

и sign_up_params имеет только

{"email"=>"ush@gmail.com", "password"=>"123456", "password_confirmation"=>"123456", "meta_type"=>"admin"}

без admin_attributes.

Атрибутами для администратора являются "degree_access" (целое число), "department" (строка).

Атрибутами для исходного пользователя являются first_name (строка), last_name (строка) и team (строка).

app / models / user.rb:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :tasks, dependent: :destroy
  belongs_to :meta, polymorphic: true, validate: true
  accepts_nested_attributes_for :meta
end

app / models / admin.rb:

class Admin < ApplicationRecord
  has_one :user, as: :meta, dependent: :destroy
end

app / models / original_user.rb:

class OriginalUser < ApplicationRecord
  has_one :user, as: :meta, dependent: :destroy
end

app / controllers / users / registrations_controller.rb:

module Users
  class RegistrationsController < Devise::RegistrationsController
    before_action -> { request.session_options[:skip] = true }
    before_action :configure_sign_up_params

    KEYS_FOR_SIGNUP = %i[
    meta_type
    email
    password
    password_confirmation
    [ admin_attributes: [ :degree_access, :department] ]
    [ original_user_attributes: [:first_name, :last_name, :team] ]
    ].freeze

    def create
      build_resource(sign_up_params)
      if resource.meta_type == 'admin'
        resource.meta = Admin.new
      elsif resource.meta_type == 'original_user'
        resource.meta = OriginalUser.new
      end

      if resource.save
        render json: resource.payload
      else
        render json:
          bad_request_params(resource.errors), status: :bad_request
      end
    end

    protected

    def configure_sign_up_params
      devise_parameter_sanitizer.permit(:sign_up,
                                        keys: KEYS_FOR_SIGNUP)
    end
  end
end

1 Ответ

0 голосов
/ 12 марта 2020

Я думаю, что вы не можете использовать эту схему

KEYS_FOR_SIGNUP = %i[
    meta_type
    email
    password
    password_confirmation
    [ admin_attributes: [ :degree_access, :department] ]
    [ original_user_attributes: [:first_name, :last_name, :team] ]
].freeze

, потому что вы получите :"[admin_attributes: [ :degree_access, :department]]" вместо ожидаемого поведения. Вы должны использовать обычный массив без литерала %i

...