1

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

楷模:

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar < ActiveRecord::Base
  belongs_to :foo
  attr_accessible :foo, :foo_id
end

控制器规格:

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

如果我将此规范更改为不必进行foo_id批量分配的形式,它将中断ActiveRecord::AssociationTypeMismatch expected Foo got String

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

describe Bar do
  it { should_not allow_mass_assignment_of(:foo_id) }
end

控制器代码非常简单:

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

有没有办法让规范在不foo_id访问的情况下运行?

4

1 回答 1

1

FactoryGirl.attributes_for忽略关联。你可以做

FactoryGirl.build(:bar).attributes

但是,这样您需要删除不需要的参数,如id, created_at,updated_at等。

我建议你创建一个特殊的方法spec_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_attributes(:bar).

于 2012-07-03T06:05:48.057 回答