具有嵌套属性的Factory Bot和Rspec和指向同一表的两个前键

时间:2018-11-27 12:13:12

标签: ruby-on-rails factory-bot rspec-rails nested-attributes

我有两个具有has_many关联的模型,即User和UserRelation模型。我的UserRelation有两个用户外键。

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

如何将嵌套属性放在参数中?

0 个答案:

没有答案