views:

291

answers:

2

I have a Proposal model that belongs to Project:

class Proposal < ActiveRecord::Base
  belongs_to :project
  has_many :articles, :as => :document, :dependent => :destroy
  has_many :sections, :through => :articles

  # proposal has project - test/unit/proposal_test.rb
  validates_presence_of :project_id
end

The route I set up to show this record is "http://domain.tld/projects/project-id/proposal", through this line in routes.rb - "map.resources :projects, :has_one => :proposal"

Now I want to test this through proposals_controller_test.rb.

  test "should show proposal" do
    get :show, :id => proposals(:one).to_param
    assert_response :success
  end

However, "rake test" keeps telling me this, and I have no idea how to fix it. Probably really easy for you guys, but new to me.

  1) Error:
test_should_show_proposal(ProposalsControllerTest):
ActiveRecord::RecordNotFound: Couldn't find Project without an ID
    app/controllers/proposals_controller.rb:18:in `show'
    /test/functional/proposals_controller_test.rb:34:in `test_should_show_proposal'

Here is my controller show logic:

  # should show proposal - test/functional/proposals_controller_test.rb
  def show
    @project = Project.find(params[:project_id])
    @proposal = @project.proposal

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @proposal }
    end
  end

A quick trip to "script/console" yields:

Loading development environment (Rails 2.3.4)
>> t = Project.first
=> #<Project id: 1, name: "Test">
>> t.proposal
=> #<Proposal id: 2, active: true, project_id: 1>

Whereas "script/console test" shows:

Loading test environment (Rails 2.3.4)
>> t = Project.first
=> #<Project id: 298486374, name: "Test">
>> t.proposal
=> nil

What is up with that wacky ID?!?! Please help me hook up associations in the test env!

A: 

First I thing noticed is that your controller is using the param 'project_id' and your test is passing a parameter of 'id'. So your find call will be searching with 'nil' in the controller which will probably cause the error your seeing.

Params is just a hash, and you can actually pass the params hash in your show call. If you want there to be a value for a 'project_id' field, then you can add that in easily. for example:

get :show, { :project_id => proposals(:one).project_id }

try something along those lines and you should be able to get the right project_id to the controller. Rails should know that the hash being passed at the end is the params hash and will create it for your controllers accordingly.

Pete
I agree that is probably where the problem is. Hence the "Couldn't find Project without an ID". This is the line that needs some guru magics - "get :show, :id => proposals(:one).to_param".
Octopus Inc
Essentially, I need to know how to replicate params[] in the functional tests and pass that to my controller...
Octopus Inc
updated the answer to show how to pass the project id value in the params hash.
Pete
I never realized that the hash passed to the get method was the substitute for all the params generated by rails routes, etc. Makes sense...
Octopus Inc
This is all well and good, however associations just don't work the same in the test environment because my fixtures have randomly generated IDs. This prevents me from associating them together in the traditional foreign key way. I still need help...
Octopus Inc
A: 

Here is what was wrong.

http://stackoverflow.com/questions/763881/automatic-associations-in-ruby-on-rails-fixtures

http://ar.rubyonrails.org/classes/Fixtures.html

  • See the section on "Label references for associations (belongs_to, has_one, has_many)"

Here is another optional explanation...


Essentially, you have to monkey around with your fixtures some and remove the _id from foreign keys to get associations working (oddly enough). The articles explain everything. After I RTFM everything starting working perfectly. Just needed to know where to look. Don't forget to "rake db:test:prepare" & "rake test" first!

Octopus Inc