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?
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.