Ruby on rails 使_id质量可分配的替代方案

Ruby on rails 使_id质量可分配的替代方案,ruby-on-rails,activerecord,rspec,factory-bot,Ruby On Rails,Activerecord,Rspec,Factory Bot,我有一个rails控制器的规范,用于测试关联模型的创建: 型号: class Foo < ActiveRecord::Base has_many :bars end class Bar < ActiveRecord::Base belongs_to :foo attr_accessible :foo, :foo_id end 如果我将此规范更改为不必使foo_idmass-assignable的形式,它将与ActiveRecord::AssociationTypeMi

我有一个rails控制器的规范,用于测试关联模型的创建:

型号:

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar < ActiveRecord::Base
  belongs_to :foo
  attr_accessible :foo, :foo_id
end
如果我将此规范更改为不必使
foo_id
mass-assignable的形式,它将与
ActiveRecord::AssociationTypeMitch预期的foo-get字符串一起中断:

@foo = FactoryGirl.create(:foo)
expect {
  post :create, { bar: FactoryGirl.attributes_for(:bar, foo: @foo )}
}.to change(Bar, :count).by(1)

控制器代码非常简单:

def create
    @bar = Bar.new(params[:bar])
    if @bar.save
      redirect_to @bar
    else
      render action: 'new'
    end
  end

有没有一种方法可以使spec运行而不使
foo\u id
可访问?

FactoryGirl
的属性忽略关联。你能行

FactoryGirl.build(:bar).attributes
但是,通过这种方式,您需要删除不需要的参数,如
id
处创建,
处更新,等等

我建议您在
spec\u helper
中创建一个特殊方法:

def build_attributes(*args)
  FactoryGirl.build(*args).attributes.delete_if do |k, v|
    ['id', 'created_at', 'updated_at'].member?(k)
  end
end

然后使用它:
post:create,:bar=>build\u属性(:bar)

FactoryGirl
.attributes\u for
忽略关联。你能行

FactoryGirl.build(:bar).attributes
但是,通过这种方式,您需要删除不需要的参数,如
id
处创建,
处更新,等等

我建议您在
spec\u helper
中创建一个特殊方法:

def build_attributes(*args)
  FactoryGirl.build(*args).attributes.delete_if do |k, v|
    ['id', 'created_at', 'updated_at'].member?(k)
  end
end

然后使用它:
post:create,:bar=>build\u attributes(:bar)

这是朝着正确方向迈出的一大步,但这种方法似乎仍然要求
foo\u id
是可批量分配的?不,在保存
@bar
之前,您应该在控制器的创建操作中添加:
@bar.foo=foo
,如果我这样做,我需要删除
params['bar']
中的
foo\u id
属性,帮助器方法首先创建了该属性?是的,如果您保护它不受批量分配的影响。您需要在
build\u attributes
helper中删除它,而不是在controller中。我不认为没有更优雅的解决方案,非常感谢!这是朝着正确方向迈出的一大步,但这种方法似乎仍然需要
foo_id
进行大规模分配?不,您应该在控制器的创建操作中添加:
@bar.foo=foo
在保存
@bar
之前,如果我这样做,我需要删除
参数['bar'中的
foo_id
属性
帮助器方法首先创建的是哪种方法?是的,如果您保护它不受批量分配的影响。您需要在
build\u attributes
helper中删除它,而不是在controller中。我不认为没有更优雅的解决方案,非常感谢!