views:

42

answers:

2

I have an accounts model that holds some basic account info (account name, website, etc). I then have a user model that has the following in the app/models/user.rb

belongs_to :account

I also have the following in my routes.rb

map.resources :account, :has_many => [:users, :othermodel]

the problem I'm facing is that the following test is failing:

test "should create user" do
  assert_difference('User.count') do
    post :create, :user => { } #this is the line it's actually failing on
  end

  assert_redirected_to user_path(assigns(:user)) #it doesn't get here yet
end

The error it gives is "Can't find Account without ID" so I kind of understand WHY it's failing, because of the fact that it doesn't have the account object (or account_id as it were) to know under what account to create the user. I have tried variations of the following but I am completely lost:

post :create, :user => { accounts(:one) } #I have the 'fixtures :accounts' syntax at the top of the test class

post :create, [accounts(:one), :user] => { }

post :create, :user => { accounts(:one), #other params for :user }

and like I said, just about every variation I could think of. I can't find much documentation on doing this and this might be why people have moved to Factories for doing test data, but I want to understand things that come standard in Rails before moving onto other things.

Can anyone help me get this working?

UPDATE:

I managed to get the test to fail in a different location, I had to ensure that the test could actually get to the create action (have some authlogic stuff in my app)

it now says

undefined method 'users' for nil:Class

So now it's saying that it can't find a users collection on my @account object in the controller, basically because it still can't find the @account even though it doesn't actually fail to find the account in question. So my before_filter :find_account works to the extent that it doesn't break, but it seem to not be finding the account.

I tried the post :create, :id => @account.id, :user => { } but to no avail. Also tried post :create, :account => accounts(:one), :user => { } and :user => { :account => accounts(:one) }, again with the same result.

A: 

I think you got the association backwards. If that's the case then Account model should belong_to :user, then User model should has_one :account.

Otherwise, since you're creating user which belongs to some account, you should pass account's :id in params:

post :create, :id => some_test_account.id, :user => {...}
Eimantas
A: 

The typical controller for the belongs_to side of a has_many association would have a create action like this:

def create
  @account = Account.find(params[:account_id])
  @user = @account.users.build(params[:user])
  if @account.save
    # handle success
  else
    # handle failure
  end
end

If your controller doesn't look like this you not be handling the parameters correctly, thus the test failure.

You can also check your routes. You should see something like:

POST /accounts/:account_id/users(.:format) {:controller=>"users", :action=>"create"}

That's another clue that Rails is setting params[:account_id] to the value for the requested account.

zetetic
I have a before_filter :get_user_account in my users_controller that finds the account by id before doing any other stuff. So all that is set up correctly.
Koby
Hmm. Have you looked in the test log?
zetetic
test log didn't show anything out of the ordinary, is there a way to make it more verbose?
Koby