Problem with my associations Users -> Accounts -> Transactions

I have three tables: users, accounts, and transactions. Users have many accounts, accounts have many transactions. So I define my models like so:

class User < ActiveRecord::Base has_many :accounts, dependent: :destroy end

class Account < ActiveRecord::Base belongs_to :user has_many :transactions, dependent: :destroy end

class Transaction < ActiveRecord::Base belongs_to :account end

Ideally on my app. When the current_user (btw, I’m also using Devise :wink: clicks shows accounts, then clicks an account to show transactions for that page - eventually I end up on /transactions?account=2 URL. Until here works fine.

In my transactions controller, however, I was to display on that page transactions for that user (current_user) for that account (id=2). I’m not sure the correct way to do this thought. Below is what I was trying:

def index @account = current_user.accounts.find_by_id(params[:accoount]) @transactions = @account.transactions.find_all_by_account(params[:accoount]); end

…but it doesn’t work :frowning: Where am I going wrong?

Btw, I get the following error:

undefined method `transactions’ for nil:NilClass

To me this tells me that @account if not found, or is returning an empty array. Am I using the wrong method, or parameters?

Please, try Users instead of current_user, like : def index

@account = Users.accounts.find_by_id(params[:accoount])

@transactions = @account.transactions.find_all_by_account(params[:accoount]);

end

Aaargh!!! I see it, I didn’t type “account” correctly. I thought I was using the method incorrectly. How did I not see that for so long?! @account = Users.accounts.find_by_id(params[:accoount]) This now works - @account = current_user.accounts.find_by_id(params[:account])

Actually I’ve changed the whole thing to:

def index @account = current_user.accounts.find_by_id(params[:account]) @transactions = @account.transactions; end

… works fine

@account = Account.find(params[:account]) should also work. A possible disadvantage of this method (depending on your application) is that a manually constructed url could show an account that does not belong to the current_user.

Colin

Consider, though, that if for whatever reason an invalid id is passed in, @account will be nil and so @account.transactions will give you a NoMethod error.

What do you want to happen at that point?

Consider, though, that if for whatever reason an invalid id is passed

in, @account will be nil and so @account.transactions will give you

a NoMethod error.

What do you want to happen at that point?

Good point. Thanks, I’ll put some checking to see if account is valid or not and handle it accordingly.

One quick way to do that is to use plain find instead of find_by_id, thus:

@account = current_user.accounts.find(params[:account])

If a user attempts to request an account that doesn’t belong to them, this will raise ActiveRecord::RecordNotFound. The default Rails rescue_from will translate that into an HTTP 404 Not Found response.

–Matt Jones