如何使用外键的强参数

时间:2014-06-13 18:51:12

标签: ruby-on-rails ruby-on-rails-4 strong-parameters

我遇到了在我的新Rails 4应用程序中允许使用外键的问题。

假设您有一个用户创建表单,您可以在其中创建用户并通过下拉列表分配用户类型。

用户模型将具有外键:user_type_id

我有一个使用FactoryGirl的RSpec测试,如果我调试并查看params,user_type的值为2,但如果我的许可证参数如下:

private 

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

我没有获得任何user_type。我也尝试过:

private 

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

但没有任何运气。

在我的用户控制器的帖子操作中允许它的方式是什么?

更新

我还没有用户界面,我尝试用TDD方式做到这一点,所以基本上是我的RSpec测试失败了。

创建用户操作如下所示:

 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

并且RSpec测试如下所示:

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

我的用户的FactoryGirl如下所示:

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

如果我调试我的@user对象,它没有添加user_type,但如果我调试params对象,它会包含user_type: 2

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您没有在工厂中创建ID。您正在创建新的关联对象。您必须在传递给控制器​​的参数中检索ID。

我建议:

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

在您的规范中:

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

然后:

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

从FactoryGirl操作中删除关联。

编辑: 如果用户类型是必需的,并且假设您在数据库中拥有它们,则只需在工厂中插入所需的user_id用于该用户类型。你不需要在之后合并params。