Diego,

You actually have a very good question here. 

I don't quite see all the foreign keys here, and I only grok 75% of your 
specific data model, so I will answer your question generally and give you some 
options rather than specifically tell you how to do it.

You probably read that the rails default is to use the class name as the 
association name. In the case of multiple associations to the same classes -- 
possibly through join tables -- this is actually a confusing way to name your 
associations. 


Consider something that is not your data model: An "Article" that has both an 
Author (user object) and an Editor (user object)

The standard way to write your association is like so:

class Article < ActiveRecord::Base
   belongs_to :user
end

But the problem here is that you actually want two relationships to two 
different user objects (one for author and another for editor).

As you have already discovered, you can use a different name for the 
association name, as long as you pass class_name as an option to your 
association declaration, like so:


class Article < ActiveRecord::Base
   belongs_to :author, class_name: "User"
   belongs_to :editor, class_name: "User"
end

In the example above, your Article table would have a foreign key for author 
and editor (my personal naming convention is to name these author_user_id and 
editor_user_id, that way the field conveys both the relationship itself and the 
class that it relates to).


The is a really, really good idea because the worst thing in an app is to have 
a relationship to a user_id and as the future developer be scratching your head 
wondering if the original developer intended that to be a "editor" or an 
"author". I strongly recommend using this style of naming convention when you 
will have multiple relationships to the same classes, as you have in the 
example below (a user's relationship to a billing can be either as a creditor 
or as a debtor). 

Remember, the association name you give is for you (& Rails) to identify that 
association elsewhere in your codebase. Although the default is to use the name 
of the foreign class, it is by no means required.


As far as you actual question (should you use a direct relationship between 
User and Debt or should you use the has_many :through relationship, using the 
billings as a join table) -- I think I understand that correctly --- there is 
no one better to answer that than you. (Without knowing more about your data 
model I can't advise).

But I can say that you should avoid duplicitous relationships (also known as 
circular dependancies). Note that if one relationship describe a creditor and 
the second one describes a debtor, that doesn't actually count as duplicitous 
(for the purpose of my argument). It would be duplicitous if a foreign key 
describes the same relationship already described in another place (like a 
different foreign key or through a join table). That's what you want to avoid. 

The confusing part of your data model is that a Debt belongs_to a user (is that 
a creditor or debtor relationship? See how using non-default association names 
as explained above can be advantageous?) 

If the context of the Debt record only has meaning by being related to a 
Billing, then it probably doesn't make sense to also make it have a user_id 
(since you can derive that user by examining the relationship to the Billing 
object). Again, since you have some tricky stuff going on with 
debtors/creditors understand that I *may* not be understanding your data model 
fully. 

I would recommend you create an old-fashioned ERD (Entity Relationship Diagram) 
on a napkin. Also you might want to learn a little bit about the ancient art of 
"3rd Normal Form". 

Hope this help! 

Jason




On Sep 20, 2014, at 3:37 PM, Diego Dillenburg Bueno <diegodillenb...@gmail.com> 
wrote:

> Hello everyone,
> 
> I'm a beginner Rails developer and right now am building a sample project to 
> show off at some job apply. The app is rather simple, I guess, but I have 
> come to some doubts on what associations to chose and why.
> 
> Basically a User can create a bill(being its creditor) and the billing can 
> have many other Users(as their debtors), so you can track up billings you 
> share with other persons, like rent, market, food orders etc, and control 
> what each one got to pay you.
> 
> Right now I have the following model:
> 
> class User < ActiveRecord::Base
>       has_many :billings, foreign_key: "creditor_id", dependent: :destroy
>       has_many :debts, foreign_key: "debtor_id", dependent: :destroy
> end
> 
> class Billing < ActiveRecord::Base
>       belongs_to :creditor, class_name: "User"
>       has_many :debts, dependent: :destroy
> end
> 
> class Debt < ActiveRecord::Base
>       belongs_to :billing
>       belongs_to :user
> end
> 
> would this be the better approach? Or something like:
> User has_many billings through debts
> Billing has_many debts ?
> 
> And in that case, would appreciate some help to model those associations, 
> because I'm still kinda lost on this flow.
> 
> Thanks in advance,
> Diego Dillenburg Bueno
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to rubyonrails-talk+unsubscr...@googlegroups.com.
> To post to this group, send email to rubyonrails-talk@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/rubyonrails-talk/CAOHSkmE893vhkwHsna6e5Ax4fCZipg965brtieXtr9Ui6OAVdw%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-talk+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-talk/2B4E0A28-10AF-4718-AB24-7F3A1D6698AD%40datatravels.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to