Using :include with find

I’m having trouble trying to figure out how to render data when you
have multiple tables and a joining table with data between them. I’ll
use the Rails Recipe #22 as an example to illustrate my trouble.

The concept is that you have readers and magazines and subscriptions:
–A reader has many subscriptions
–A reader has many magazines through subscriptions
–A magazine has many subscriptions
–A magazine has many readers through subscriptions
–A subscription belongs to both a reader and a magazine

In the example the subscription also has some data such as number of
issues. My problem is this how do I for a specific reader show each
magazine he subscribes to and the number of issues he bought. This
requires data from both the subscription and magazine model in one
loop.

So in my controller I try something like this for the show method:
@reader = Reader.find(params[:id])
@subs = @reader.magazines.find(:all, :include => :subscriptions)

In my view code I spit out some data with the @reader object and then
try to show the list of magazines and the number of issues for each
magazine (Basically there is a one-to-one relationship between a
magazine and an idividual subscription so I want to display them in one
row). View code below:

<% for each sub in @subs %>
Magazine: <%= sub.mag_name %> / Issues: <%=
sub.subscription.num_of_issues %>
<% end %>

What happens is that I get an error of undefined method for
num_of_issues instead of the data in the num_of issues attribute. I’m
assuming that this is just syntax I’ve misunderstood. If I run the
find in the console it appears to be pulling back all of the data I
just can’t figure out how to access each bit in a loop. I’ve searched
all over the web this afternoon and find tons of examples that show
controller code or console statements, but rarely code from the
controller and the view. Any help would be greatly appreciated.

–Eric

[email protected] wrote:

So in my controller I try something like this for the show method:
@reader = Reader.find(params[:id])
@subs = @reader.magazines.find(:all, :include => :subscriptions)

That’s a bit confusing @reader.magazines.find is returning an array of
magazines, calling it @subs is weird.

Magazine: <%= sub.mag_name %> / Issues: <%=
sub.subscription.num_of_issues %>
A magazine has many subscriptions, so magazine.subscription doesn’t
exist. you want to do something to magazine.subscriptions
If however you just want to count the number of subscriptions for each
magazine that the reader subscribes to then you a doing a lot of work
since you are pulling all these subscriptions across from the db into
rails just to count them (have a look at the ActiveRecord::Calculations)

Fred

[email protected] wrote:

I’m having trouble trying to figure out how to render data when you
have multiple tables and a joining table with data between them. I’ll
use the Rails Recipe #22 as an example to illustrate my trouble.

The concept is that you have readers and magazines and subscriptions:
–A reader has many subscriptions
–A reader has many magazines through subscriptions
–A magazine has many subscriptions
–A magazine has many readers through subscriptions
–A subscription belongs to both a reader and a magazine

Hi Eric

I don’t know if it answers your question but this is what I do… and it
works

In your models
reader
has_many : subscriptions
has_many :magazines, :through => : subscriptions

magazine
has_many : subscriptions
has_many :readers, :through => : subscriptions

subscription
belongs_to :reader
belongs_to :magazine

in your controller action list for example

@subscriptions_pages, @subscriptions = paginate :subscriptions, :order
=> sort, :conditions => [… to be defined…], :include=>[reader,
:magazine ], :per_page => subscriptions_per_page

(note : you can even include upward levels… like :include=>[reader,
{:magazine=>:group}] if a group has many magazins… isn’t wonderful ?)

in your view list.rhtml

<% for subscription in @ subscriptions %> <%= subscription.reader.name %> <%= subscription. magazine.title %> .... <% end %>

I build the conditions with the EZ-Where plugin

http://brainspl.at/articles/2006/06/30/new-release-of-ez_where-plugin

very very useful to build complex where conditions… I can send you
some examples

Thanks for the responses. I actually got things working using
something like this: sub.subscriptions.first.num_of_issues. I’ll be
taking a look at both of your suggestions though going forward,
especially the EZ-Where plugin.