1
votes

I am having an issue with foreign keys being permitted in my new Rails 4 application.

Lets say you have a user create form, where you can create a user and assign a user type though a dropdown.

The user model will then have a foreign key: user_type_id.

I have a RSpec test which uses FactoryGirl, and if I debug and look at params the user_type has the value 2, but if my permit params look like this:

private 

def user_params
  params.require(:user).permit(:name, :password, :user_type_id)
end

I won't get any user_type out. I have also tried with:

private 

def user_params
  params.require(:user).permit(:name, :password, user_type_attributes: [:user_type_id]) 
end

but without any luck.

What is the way to permit it in my post action in my User controller?

Update:

I don't have a UI yet, I try to do this the TDD way, so basically it is my RSpec-tests which fails.

The create user action looks like this:

 def create
    @user = User.new(user_params)
    authorize @user

    respond_to do |format|
        if @user.save
            format.html { render json: @user, status: :created, location: @user }
            format.json { render json: @user, status: :created, location: @user }
        else
            format.html { render json: @user, status: :unprocessable_entity, location: @user }
            format.json { render json: @user.errors, status: :unprocessable_entity }
        end
    end
end

and the RSpec test looks like this:

it 'should create a user' do
                expect {
                    post :create, { :user => FactoryGirl.attributes_for(:User) }
                }.to change(User, :count).by(1)
            end

The FactoryGirl for my user looks like this:

FactoryGirl.define do
    factory :User do |f|
        f.email { Faker::Internet.email }
        f.password { '12345678' }
        f.password_confirmation { '12345678' }
        f.user_type { FactoryGirl.create(:UserType) }
    end
end

If I debug my @user object it doesn't have a user_type added, but if I debug the params object, it does, contain a user_type: 2

Any ideas?

1
Can you post the user create form? Specifically the dropdown.Joe Kennedy
Agreed with JKen13579. We need to see the form.Ege Ersoz
I have updated the question, basically I don't have a UI, but are testing it with RSpec.Dofs

1 Answers

1
votes

You are not creating an Id in the Factory. You are creating the new associated object. You will have to retrieve the ID in the params passed to the controller.

I suggest:

FactoryGirl.define do
    factory :User do |f|
        f.email { Faker::Internet.email }
        f.password { '12345678' }
        f.password_confirmation { '12345678' }
        f.user_type 999
    end
end

In your spec:

before(:each) do
  type = FactoryGirl.create(:UserType, id: 999)
end

And then:

it 'should create a user' do
  expect { :create, { :user => FactoryGirl.attributes_for(:User)}
                     }.to change(User, :count).by(1)
end

And remove the association from the FactoryGirl action.

EDIT: If the user type is mandatory, and assuming that you have them in the database, you just need to insert in the factory the user_id you want for that user type. And you won't need to merge the params after.