Factory Bot и Rspec с вложенными атрибутами и двумя первыми ключами к одной таблице - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть две модели с ассоциацией has_many, модель User и UserRelation.У моего UserRelation есть два внешних ключа для User.

class UserRelation < ApplicationRecord

    belongs_to :user
    belongs_to :user2, class_name: 'User', foreign_key: 'user2_id'

end  

Модель пользователя:

class User < ApplicationRecord

    rolify
    has_secure_password

    has_many :user_relations, dependent: :destroy
    has_many :user2, class_name: 'UserRelation', foreign_key: 'user2_id', dependent: :destroy

    accepts_nested_attributes_for :user_relations, allow_destroy: true

    validates :name, :last_name, :email, :password, presence: true
    validates_length_of :password, maximum: 72, minimum: 8, allow_nil: true, allow_blank: false

    before_create :assign_default_role

    def assign_default_role
        add_role(:employe)
    end
end

Мой UserController:

module Api
  module V1
    class UsersController < Api::V1::ApiController
      before_action :authenticate_user
      before_action :set_user

      def update
        if @user.update(user_params)
          render json: @user
        else
          render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
        end
      end

      private

      def user_params
        params.require(:user).permit(:name, :last_name, :password, :email, user_relations_attributes: [:id, :user_id, :user2_id, :_destroy])
      end

      def set_user
        @user = User.find(params[:id])
      end
    end
  end
end

Я создаю свой завод для обеих моделейс фабричным ботом.

FactoryBot.define do
    factory :user do
        name { FFaker::Lorem.word }
        email { FFaker::Internet.email }
        last_name { FFaker::Lorem.word }
        password 'secret123'

        factory :user_relation do
            user
            association :user2, factory: :user
        end

        factory :admin do
            after(:create) do |user|
                user.remove_role :employe
                user.add_role :admin
            end
        end
    end
end

В моем тесте я пытаюсь обновить пользователя с помощью attribute_for, но в эти атрибуты я хочу иметь user_relation_attributes, чтобы мои тесты выполнялись.Я пробовал это, но не сработало.

describe 'PUT /api/v1/users/:id' do

  context 'Unauthenticated' do
    it_behaves_like :deny_without_authorization, :put, '/api/v1/users/-1'
  end

context 'admin' do

    let(:admin) {create(:admin) }
    let(:user) {create(:user) }
    let(:user2) {create(:user) }
    let(:user_params) {attributes_for(:user) }
    let(:content) {attributes_for(user_id: user.id, user2_id: user2.id)}

    before do
            put "/api/v1/users/#{user.id}", params: { user: user_params.merge!(content) }, headers: header_with_authentication(admin)
    end

    it { expect(UserRelation.count).to eq(1) }

  end
end

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

...