2013-09-01 38 views
5

Từ hiểu biết của tôi, giá trị trả về từ phương thức 'to_create' của nhà máy bị bỏ qua. Điều này có nghĩa là đối tượng được trả về từ phần 'build' hoặc 'initialize_with' của nhà máy là đối tượng cuối cùng được trả về khi gọi 'create' trong một thử nghiệm.FactoryGirl to_create return value

Trong trường hợp của tôi, tôi đang sử dụng biến thể của Mẫu Kho lưu trữ. Tôi ghi đè phần 'to_create' của nhà máy để bao gồm cuộc gọi đến phương thức lưu 'lưu'. Phương thức này không sửa đổi đối tượng đã cho, nhưng trả về một đối tượng biểu diễn dạng tồn tại của bản gốc.

Tuy nhiên, thể hiện được trả lại từ khối 'xây dựng' được trả lại từ nhà máy chứ không phải trường hợp được tạo trong khối 'to_create'. Trong mã của tôi, điều này có nghĩa là biểu mẫu "không được hỗ trợ" của đối tượng được trả về, không phải đối tượng có thuộc tính được cập nhật (ví dụ: 'id') từ hành động lưu.

Có cách nào để buộc giá trị trả lại của 'tạo' là kết quả của khối 'to_create' hoặc một số giá trị được tạo trong khối đó không?

class Foo 
    attr_accessor :id, :name 
    ... 
end 

class FooRepository 
    def self.create(name) 
    Foo.new(name) # this object is not yet persisted and has no .id 
    end 

    def self.save(foo) 
    # this method must not guarantee that the original Foo instance 
    # will always be returned 
    ... 
    updated_foo # this is a duplicate of the original object 
    end 

    ... 
end 

FactoryGirl.define do 
    factory :foo, class: FooRepository do 
    # create an example Foo 
    initialize_with { FooRepository.create(name: "Example") } 
    # save the Foo to the datastore, returning what may be a duplicate 
    to_create {|instance| FooRepository.save(instance)} 
    end 
end 

describe FooRepository do 
    it "saves the given Foo to the datastore" do 
    foo = create(:foo) 
    foo.id #=> nil 
    ... 
    end 
end 

Trả lời

4

Tôi không có câu trả lời cho bạn ngoài "raise an issue", xin lỗi.

to_create callback

Giá trị mặc định trông như thế này:

$ grep to_create lib/factory_girl/configuration.rb 
to_create {|instance| instance.save! } 

Vấn đề chính là ActiveRecord đổi bản thân ở vị trí khi bạn gọi save! trên đó. FactoryGirl sẽ bỏ qua bất kỳ đối tượng mới nào được trả lại từ to_create.

Một hack nhanh chóng nếu bạn muốn ghi đè mặc định tạo ra chiến lược:

module FactoryGirl 
    module Strategy 
    class Create 
     def association(runner) 
     runner.run 
     end 

     def result(evaluation) 
     evaluation.object.tap do |instance| 
      evaluation.notify(:after_build, instance) 
      evaluation.notify(:before_create, instance) 
      instance = evaluation.create(instance) # <-- HACK 
      evaluation.notify(:after_create, instance) 
     end 
     end 
    end 
    end 
end 

... Hoặc làm điều này để to_create móc của bạn để bắt chước Rails' sửa đổi tại chỗ:

to_create do |record| 
    new_record = YourRepositoryHere.new.create(record) 
    record.attributes = new_record.attributes # For example 
    new_record # Return the record just in case the bug is fixed 
end 

May mắn nhất. :(

+0

Tốt! Nó đã giúp với một số vấn đề khác nhau, nhưng câu trả lời rất tốt đẹp tuy nhiên! :) – Aleks