Forum: Ruby on Rails newbie: displaying a denormalized list of records.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ed Schechter (Guest)
on 2005-11-28 06:50
I am trying to list my orders showing customer names rather than
customer IDs.  I am not having much luck.


I have a table called orders, having a 'customer_id' field.  I also have
a table called customers, which has a field called 'id', as well as a
field called 'name'.

In the orders model, I specify that order belongs_to customer, and in
the customer model, I specify that the customer has_many orders.

As a first shot, I assumed that in the list view for orders, I could
replace the working line

               <td><%=h order.send('customer_id') %></td>

with something like

               <td><%=h order.send('order.customer.name') %></td>.

That didn't work.

My current iteration defines the following method in order.rb

	def self.find_all_denormalized
		sql = "	SELECT orders.*,  						               customers.name as
customerName
                        From orders left join customers
                                          on customer_id = customers.id
"
		orders_denormalized = Order.find_by_sql(sql)
		return orders_denormalized
	end

and in order_controller.rdb, I have redefined list as

  def list
    @order_pages, @orders = paginate Order.find_all_denormalized,
:per_page => 10
  end

This is not working.  I am getting a message like:

wrong constant name
#<Order:0x394ba68>#<Order:0x394ba20>#<Order:0x394b9d8>#<Order:0x394b990>#<Order:0x394b948>

-------------------------------------------------------

Two questions:  why is my approach not working, and is there a
fundamentally better (more Rails) way to do this?

Thanks in advance

Ed
Jonathan L. (Guest)
on 2005-11-28 07:20
hi Ed,

I think part of your problem is that you're using the built-in paginate
instead of this one:

def paginate_collection(collection, options = {})
     default_options = {:per_page => 10, :page => 1}
     options = default_options.merge options

     pages = Paginator.new self, collection.size, options[:per_page],
options[:page]
     first = pages.current.offset
     last = [first + options[:per_page], collection.size].min
     slice = collection[first...last]
     return [pages, slice]
   end

You should use the above function anytime you want to paginate a
collection returned from a custom query (just add this func to your
application.rb).

As for the rails way to get the customer name, you should be able to do:

order.customer.name

anywhere you have an actual object named 'order' (in which case you
won't need a custom query at all (or the alternate paginate method above
(but it was included for future reference I suppose :)))).  This
statement is actually calling a method named 'customer_id' of the order
object (see documentation on 'send').

<%=h order.send('customer_id') %>

The reason why that part of your code isn't working is because order has
no method named 'customer.name'.  The proper way to do what you intended
is:

<%=h order.customer.name %>

Hope this helps!
--Jonathan



Ed Schechter wrote:
> I am trying to list my orders showing customer names rather than
> customer IDs.  I am not having much luck.
>
>
> I have a table called orders, having a 'customer_id' field.  I also have
> a table called customers, which has a field called 'id', as well as a
> field called 'name'.
>
> In the orders model, I specify that order belongs_to customer, and in
> the customer model, I specify that the customer has_many orders.
>
> As a first shot, I assumed that in the list view for orders, I could
> replace the working line
>
>                <td><%=h order.send('customer_id') %></td>
>
> with something like
>
>                <td><%=h order.send('order.customer.name') %></td>.
>
> That didn't work.
>
> My current iteration defines the following method in order.rb
>
> 	def self.find_all_denormalized
> 		sql = "	SELECT orders.*,  						               customers.name as
> customerName
>                         From orders left join customers
>                                           on customer_id = customers.id
> "
> 		orders_denormalized = Order.find_by_sql(sql)
> 		return orders_denormalized
> 	end
>
> and in order_controller.rdb, I have redefined list as
>
>   def list
>     @order_pages, @orders = paginate Order.find_all_denormalized,
> :per_page => 10
>   end
>
> This is not working.  I am getting a message like:
>
> wrong constant name
> 
#<Order:0x394ba68>#<Order:0x394ba20>#<Order:0x394b9d8>#<Order:0x394b990>#<Order:0x394b948>
>
> -------------------------------------------------------
>
> Two questions:  why is my approach not working, and is there a
> fundamentally better (more Rails) way to do this?
>
> Thanks in advance
>
> Ed
This topic is locked and can not be replied to.