title: What's difference between Factory.build and Factory.attributes_for?
body: <p>In our rspec test for rails 3.1.0 app, we use both Factory.build and Factory.attributes_for. What we found is that if we change the Factory.build to Factory.attributes_for, one case for data validation failed. Furthermore the Factory.attributes_for did not test it right. I am wondering what's the difference between those two and, how to use them in rspec. </p>
  
  <p>In our model test, we are using Factory.build. In controller test for update or new, we use Factory.attributes_for. we just found out a case in controller test that Factory.attributes_for did not test it right and failed the case which has passed in model validation with Factory.build. </p>
  
  <p>Thanks so much.</p>
  
  <p>UPDATE:
  Here is a rspec case in rfq model:</p>
  
  <pre><code>  it "should not have nil in report_language if need_report is true" do
      rfq = Factory.build(:rfq, :need_report =&gt; true, :report_language =&gt; nil)
      rfq.should_not be_valid
    end
  </code></pre>
  
  <p>Here is a rspec case in rfq controller:</p>
  
  <pre><code>it "should be successful for corp head" do
    session[:corp_head] = true
    session[:user_id] = 1
    s = Factory(:standard)
    rfq = Factory.attributes_for(:rfq, :need_report =&gt; true, :report_language =&gt; 'EN')
    rfq[:standard_ids] = [s.id] # attach standard_id's to mimic the POST'ed form data
    get 'create', :rfq =&gt; rfq
    response.should redirect_to URI.escape("/view_handler?index=0&amp;msg=RFQ saved!")  
  end
  </code></pre>
  
  <p>The controller case above failed because of the validation failure. The failure in controller case is caused by addition of the line below to the create of controller rfqs.</p>
  
  <pre><code>  @rfq.report_language = nil unless params[:need_report]
  </code></pre>
  
  <p>However the case in rfq model (see above for rfq model) has passed successfully. It is .build in model test and .attributes_for in controller test.</p>
  
  <p>UPDATE:</p>
  
  <p>The right statement should be:</p>
  
  <pre><code>@rfq.report_language = nil unless params[:rfq][:need_report] == 'true'
  </code></pre>
  
  <p>OR</p>
  
  <pre><code>@rfq.report_language = nil if params[:rfq][:need_report] == 'false'
  </code></pre>
  
  <p><code>params[:need_report]</code> returns nothing and is not the right way to retrieve data from the params.</p>