Through Associations

Hi,

I’m a total noob to rails. I’m working my way through my first app and
I desperately need help with through associations in rails.

Task: get number of unread articles.

Database structure:

A. Users has_many :activity has_many :article, :through => :activity

B. Activity belongs_to :user belongs_to :article

C. Articles (user_id,feed_id,is_read) has_many :reading has_many :user, :through => :reading

belongs_to :feed

Any article that is in this table has been read and the “is_read”
field has been set to true.

D. Feeds has_many :article

How do I go about getting the number of unread articles for a given

user and feed?

Any help will be greatly appreciated.

Thanks in advance.

Best, Farhan

Farhan wrote:

Hi,

I'm a total noob to rails. I'm working my way through my first app and I desperately need help with through associations in rails.   

Through associations can be a bit complex for a beginner. Are you sure you don't want to start with something simpler? Have you worked through the tutorial in AWDWR yet?

Task: get number of unread articles.

Database structure: A. Users has_many :activity has_many :article, :through => :activity

Well, for starters, you should always use plurals with has_many relationships. So, "has_many :activities, has_many :articles, :through => :activities", etc. AWDWR would have taught you this, and many other fundamental concepts.

B. Activity belongs_to :user belongs_to :article   

good. But I'm not sure I understand the purpose of this model. What's an "activity" as it relates to a user and an article?

C. Articles (user_id,feed_id,is_read) has_many :reading has_many :user, :through => :reading belongs_to :feed

Again, ":has_many :readings"

Any article that is in this table has been read and the "is_read" field has been set to true.   

What table? Articles? I think you forgot to post a description of your "Reading" model.

D. Feeds has_many :article

:articles

How do I go about getting the number of unread articles for a given user and feed?   

Not sure I can really help here without a better understanding of the purpose of the Activity model and the structure of your Reading model.

Hi John,

Thanks for replying. I'm will be getting the AWDWR book this evening.

Okay; so I made the changes to pluralize the associations for has_many. Thanks for the tip; makes the code more readable.

I actually made a couple of typos in the "Database Structure". I had changed the name of the "readings" to "activity" (now "activities"). The new database structure is as follows with the changes you requested:

Database structure: A. Users has_many :activities has_many :articles, :through => :activities

B. Activity (user_id,feed_id,is_read) belongs_to :user belongs_to :article

C. Articles has_many :activities has_many :users, :through => :activities belongs_to :feed

D. Feeds has_many :articles

The activity model will keep track of all read articles for the user. That is when a user reads an article it gets added to the "activities" table. This table has the user_id, article_id, and the is_read columns. Any article that is added to the activity model has the is_read column set to "true".

Hope this helps; otherwise let me know and I will provide more information.

Thanks, Farhan

insha wrote:

Hi John,

Thanks for replying. I'm will be getting the AWDWR book this evening.

Okay; so I made the changes to pluralize the associations for has_many. Thanks for the tip; makes the code more readable.

I actually made a couple of typos in the "Database Structure". I had changed the name of the "readings" to "activity" (now "activities"). The new database structure is as follows with the changes you requested:

Database structure: A. Users has_many :activities has_many :articles, :through => :activities

B. Activity (user_id,feed_id,is_read) belongs_to :user belongs_to :article

C. Articles has_many :activities has_many :users, :through => :activities belongs_to :feed

D. Feeds has_many :articles

The activity model will keep track of all read articles for the user. That is when a user reads an article it gets added to the "activities" table. This table has the user_id, article_id, and the is_read columns. Any article that is added to the activity model has the is_read column set to "true".

Hope this helps; otherwise let me know and I will provide more information.

Thanks, Farhan

Alright, first... at B. above, you say the activity table has a "feed_id" column, but below you say it's "article_id". I 'm going to plow forward with the second and ignore the first, since that what it should be.

Ok, so now we want to get all the *read* articles for a particular user.

Add something like this to your User class. has_many :readings, :class_name => 'Activity', :conditions => 'is_read = 1' has_many :read_articles, :through => :readings

I hope that helps.

John,

Thank you. I will try this two liner solution. Yes, in B the activity table has the "article_id" and not "feed_id", sorry.

Thank you for your patience, Farhan

Here's another scenario, since I'm getting confused:

I have the following Models:

A = User (name) B = Feed (name) C = Article (feed_id, title) D = Reading (user_id, article_id, is_read)

What would be the simplest/easiest way to associate, using :through associations, these models so that I can easily do the following:

1. Get all articles that a user *has* read 2. Get all articles that a user has *not* read

Best, Farhan