2

I have created a functioning e-commerce platform where Members can buy books. Everything works fine, But I would like to group all of my Orders in my Index Page by Author.

Currently I am able to group each Author, but then every existing Book Order gets listed under each Author. As oppose to only listing the Book Orders corresponding to that Author.

EX. of what I'd like in my Orders Page

###Orders grouped by Authors
Author1
  Book1 belongs_to Author1   ###BookOrders grouped by Author
  Book2 belongs_to Author1  
  Book3 belongs_to Author1

Author2
  Book1 belongs_to Author2
  Book2 belongs_to Author2

Author3
  Book1 belongs_to Author3

MODELS

class Order < ActiveRecord::Base
  attr_accessible :author_id, :book_id, :user_id, :order_date

  belongs_to :book
  belongs_to :user

end

class Book < ActiveRecord::Base
  attr_accessible : author_id, :title, :price

  belongs_to : author
  has_many :orders
end

class Author < ActiveRecord::Base
  attr_accessible :name

  has_many :books
end  

CONTROLLER

def index  

  ###How Can I combine this so it Groups Book Orders By Author  

  ###Groups Orders by Author
  @orders = Order.find(:all, :order => 'author_id, id', :limit => 50)
  @author_orders = @orders.group_by { |order| order.book.author.name }

  ###Groups Orders by Book
  @orders = Order.find(:all, :order => 'author_id, id', :limit => 50)
  @book_orders = @orders.group_by { |order| order.book.title }

end

VIEWS

<% @author_orders.each do |author, orders| %>
  <h2><%= author %> </h2>

  <% @book_orders.each do |book, orders| %>
     <h4><%= book %> </h4>

  <% end %>

<% end %>
Serge Pedroza
  • 2,160
  • 3
  • 28
  • 41

2 Answers2

2

Why not instead:

Model:

class Author < ActiveRecord::Base
  attr_accessible :name

  has_many :books
  has_many :orders, through: :books
end

Controller:

def index  
  @authors = Author.includes(:orders)
end

View

<% @authors.each do |author| %>
  <h2><%= author.name %> </h2>

  <% author.orders.each do |order| %>
     <h4><%= order.book.title %> </h4>
  <% end %>

<% end %>

Update:

To display only those authors who have an order you need unfortunately to do some gymnastics. Also previous includes will not save you completely from N+1 and needs to be improved.

  @authors = Author.includes(orders: :books).where('orders.id IS NOT NULL')
BroiSatse
  • 44,031
  • 8
  • 61
  • 86
1

You are really close I think.

You just need to get your books from the order that belongs to the author.

Like this...

<% @author_orders.each do |author, orders| %>
  <h2><%= author %> </h2>

  <% orders.each do |order| %>
     <h4><%= order.book %> </h4>

  <% end %>

<% end %>
John C
  • 4,276
  • 2
  • 17
  • 28