Best Practice For Displaying Data

Simplified, I have the following relationships …

term has many swimming_classes and a swimming_class belongs to a term
swimming_pool has many swimming_classes and a swimming_class belongs to
a
swimming_pool

terms (date_from)------ swimming_classes (start_date) ------
swimming_pools
(name)

I want to order my output as …

Term (date_from DESC)
Swimming Pool (name ASC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Pool (name ASC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)

etc.

In my controller, I’m currently just getting terms (@current_term =
Term.find_current_term)
and then pass that off to the view but this leaves me a lot of work to
do to
get the output I need. It seems I have to jump about a bit and it’s not
nice…

If someone can just point me to the right place where I can read up on
displaying data where data doesn’t run as nice as Invoice -> Order ->
LineItem

CIA

-ants

Anthony G. wrote:

Simplified, I have the following relationships …

term has many swimming_classes and a swimming_class belongs to a term
swimming_pool has many swimming_classes and a swimming_class belongs to
a
swimming_pool

terms (date_from)------ swimming_classes (start_date) ------
swimming_pools
(name)

I want to order my output as …

Term (date_from DESC)
Swimming Pool (name ASC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Pool (name ASC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)
Swimming Class (start_date DESC)

etc.

In my controller, I’m currently just getting terms (@current_term =
Term.find_current_term)
and then pass that off to the view but this leaves me a lot of work to
do to
get the output I need. It seems I have to jump about a bit and it’s not
nice…

No you don’t. Just use :include and/or :joins to get all the Terms,
Pools, and Classes in one big query.

If someone can just point me to the right place where I can read up on
displaying data where data doesn’t run as nice as Invoice → Order →
LineItem

But your data does run as nice as Invoice → Order → LineItem. You
just need to use the :order options in your find statement.

With that in mind, then, your code will be something like the following
(untested, and I’m not sure about the :order syntax):
@terms = Term.find(:all, :include => {:swimming_pools =>
:swimming_classes}, :order => ‘terms.date_from desc,
swimming_pools.name, swimming_class.start_date desc’}

CIA

-ants

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Oct 29, 2009, at 6:07 PM, Anthony G. wrote:

Simplified, I have the following relationships …

term has many swimming_classes and a swimming_class belongs to a term
swimming_pool has many swimming_classes and a swimming_class belongs
to a swimming_pool

terms (date_from)------ swimming_classes (start_date) ------
swimming_pools (name)

We all speak Rails here, so just to clarify:

class Term
has_many :swimming_classes
has_many :swimming_pools, :through => :swimming_classes, :order =>
‘name’
end

class SwimmingClass
belongs_to :term
belongs_to :swimming_pool
end

class SwimmingPool
has_many :swimming_classes, :order => ‘start_date DESC’
end

You probably noticed the association from Term to SwimmingPool that I
tossed in there–be patient.

    Swimming Class (start_date DESC)
    Swimming Class (start_date DESC)

etc.

OK, so the view has

    <% @terms.each do |term| -%>
  • Term: <%= term.date_from %>
      <% term.swimming_pools.each do |swimming_pool| -%>
    • Pool: <%= swimming_pool.name %>
        <% swimming_pool.swimming_classes.each do | swimming_class| -%>
      • Class starts: <%= swimming_class.start_date %>
      • <% end -%>
    • <% end -%>
  • <% end -%>

CIA

-ants

In your controller, you seem to say that you’re getting a single term,
but you said “date_from DESC”. Since it doesn’t make much sense to
specify a sort order if there is only one, I’ll assume that you might
get more than one (perhaps with a date range).

@terms = Term.commencing_between_now_and(params[:date])

and then in the model:

class Term
def self.commencing_between_now_and(future_date)
find(:all, :include => { :swimming_pools => :swimming_classes },
:conditions => [‘date_from BETWEEN ? AND ?’, Date.today,
future_date])
end
end

Of course, you could add your own :order option to the find, but I
think that it will work as-is.

I suspect that the view is quite a bit simpler than what you have now
(since you said it was a “lot of work”). Generally, if you can put
the data you want into a form that is inherently ordered (like an
Array or an ActiveRecord::Association proxy), then your output becomes
simpler. Even if you have to crunch the data a bit in the model (or
the controller) first and a Hash is more natural, you can always loop
in your view on:

<% my_data.keys.sort do |key| -%>
<%= my_data[key] %>
<% end -%>

or turn your hash into an association list (i.e., an array of pairs
[key, value]) and pre-sort it before the view does its thing.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Doh, I didn’t think of linking pools to terms in the Term model.

that was what I was missing. Your other points are correct but in the
example I gave, there is only one current term (so the :order date_from
isn’t needed) but for previous and future terms,the :order => date_from
is
needed.

Thanks for your help

-ants

2009/10/30 Rob B. [email protected]

belongs_to :swimming_pool
I want to order my output as …

      <li>Pool: <%= swimming_pool.name %>

<% end -%>
If someone can just point me to the right place where I can read up on
you said “date_from DESC”. Since it doesn’t make much sense to specify a
:conditions => [‘date_from BETWEEN ? AND ?’, Date.today,
ActiveRecord::Association proxy), then your output becomes simpler. Even if
-Rob

Rob B. http://agileconsultingllc.com
[email protected]

–
100% naturally selected. 0% designed.