Reputation: 21
I just opening up Factory_Girl and I'm trying to figure out how to build dependent factories, most of the questions seem outdated due to the new release.
I'm using associations but other than creating the associated object, that object doesn't seem to be associated or related to the main object in anyway
Basically here's what i have
factory :computer do
serial_no "12345"
end
factory :allocation do
association :computer_id, factory: :computer
end
allocation belongs_to computer and computer has_many allocations basically an allocation is a record of any time a computer gets moved or whatnot.
I'm not sure what I'm doing wrong but every time I run this, the computer_id of allocation is '1', but the ID of computer is something random (usually a number between 0-20), and then my test fails because it can't find the proper computer object.
Edit: As if it weren't confusing enough, the actual class name is Assignment, i was attempting to simply. Here's the actual code thats involved, the actual code has no issues because computer_id and user_id are passed to the create method as params during creation.
describe "GET index" do
it "assigns assignments as @assignment" do
Assignment.any_instance.stubs(:valid?).returns(true)
assignment = FactoryGirl.create :associated_assignment
get :index, {}, valid_session
assigns(:assignments).should eq([assignment])
end
end
The Factories involved are
factory :user do
fname "John"
lname "Smith"
uname "jsmith"
position "placeholder"
end
factory :computer do
asset_tag "12345"
computer_name "comp1"
make "dell"
model "E6400"
serial_no "abc123"
end
factory :associated_assignment, class: Assignment do
association :user_id, factory: :user
association :computer_id, factory: :computer
assign_date '11-11-2008'
end
And the controller is:
def index
@assignments = []
@computers = Computer.all
Computer.all.each do |asset|
@assignments << Assignment.where(:computer_id => asset.id).order("assign_date ASC").last
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: @assignments }
format.xls { send_data @assignments.to_xls }
end
At the moment i am running this alternative test to check my ids:
describe "GET index" do
it "assigns assignments as @assignment" do
Assignment.any_instance.stubs(:valid?).returns(true)
assignment = FactoryGirl.create :associated_assignment
get :index, {}, valid_session
assigns(:computers).should eq([assignment])
end
end
Which returns something to the effect of the following, where the ID of computer is random but computer_id of assignment is always 1.
Failure/Error: assigns(:computers).should eq([assignment])
expected: [#<Assignment id: 12, user_id: 1, computer_id: 1, assign_date: "2008-11-11", created_at: "2012-09-10 23:59:48", updated_at: "2012-09-10 23:59:48">]
got: [#<Computer id: 14, serial_no: "abc123", asset_tag: 12345, computer_name: "comp1", make: "dell", model: "E6400", created_at: "2012-09-10 23:59:48", updated_at: "2012-09-10 23:59:48">]
Upvotes: 2
Views: 1113
Reputation: 5399
I think the problem is with :computer_id vs. :computer. Here's one way to do it that uses FactoryGirl's ability to infer factories and associations:
factory :computer do
serial_no "12345"
end
factory :allocation do
computer
end
Further, if you want each computer to have a unique serial number in your specs, use:
sequence :serial_no do |n|
"1234#{n}"
end
factory :computer do
serial_no
end
factory :allocation do
computer
end
Factory Girl is aware of your model and its associations, so it can pick them up and infer how to create related objects.
Thus:
allocation = FactoryGirl.create :allocation
creates an Allocation object and an associated Computer with a serial number of 12340. The id of the Computer object will already be in the Allocation's computer_id field so the relation is completely set up. allocation.computer will work, and allocation.computer_id will be the same as allocation.computer.id.
This uses some syntax sugar of FactoryGirl. You can be more explicit by supplying association (field) names and factory names:
factory :computer do
serial_no "12345"
end
factory :allocation do
association :computer, factory: :computer
end
Upvotes: 1
Reputation: 616
Factories don't guarantee what ids anything will have. But you can find the proper computer object via:
allocation = FactoryGirl.create(:allocation)
computer = allocation.computer
Upvotes: 2