Question

I have created a functioning e-commerce platform where Members can buy books. Everything works fine, except that typically after a Member buys a book, I would like to display the books that are Coming Soon, and the Books that he's bought on one page.

For Example, if the index page shows a Total of 10 Books(5 Books are Available & 5 Coming Soon).

And lets say a Member Buys 3 Coming Soon Books.

I'd like the page to display (5 Books Available, 2 ComingSoon, & the 3 Books he's Bought)=10 Total

Currently, I've defined Book Availability in my Book Model. Is there a way to subtract two Arrays so that I am able to get the 2 Coming Soon Books he hasn't Bought?

(5 Coming Soon Books - 3 Books he Bought) = 2 Coming Soon

EX:

5 Available Books {1, 2, 3, 4, 5}

5 Coming Soon Books {6, 7, 8, 9, 10}

3 Books Purchased {6, 8, 9}

I need to subtract 5 Coming Soon - 3 Books Purchased giving me

2 Coming Soon Books Left {7, 10}

Then I can Display 5 Available Books, 3 Books Purchased, and 2 Coming Soon

Here is my code, any help would be really appreciated.

MODELS

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :member

    has_many :books, through: :orders
    has_many :orders, :dependent => :destroy

end

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

  belongs_to :user
  belongs_to :book

end

class Book < ActiveRecord::Base
  attr_accessible :description, :pages, :title, :available_in, :price, :release_date
  belongs_to :publisher      


  has_many :orders
  has_many :users, through: :orders

  ###Available Book
  def book_is_available
    self.release_date < Date.today 
  end

  ###Coming Soon or Not Available
  def book_is_not_available(issue)
    if Date.today < self.release_date
      book.id
    end
  end

end

CONTROLLER

class BooksController < ApplicationController

def index
  @books = Book.all
    @orders = current_user.orders
    respond_to do |format|
      format.html
      format.json  { render :json => @issues }
    end
  end
end

SCHEMA

create_table "users", :force => true do |t|
  t.string   "name"
  t.string   "email"
  t.boolean  "member",             :default => false ###Becomes Member on SignUp
  t.datetime "created_at",         :null => false
  t.datetime "updated_at",         :null => false
end

create_table "orders", :force => true do |t|    ###Created when Purchased a BOOK
  t.integer  "user_id"
  t.integer  "book_id"
  t.date     "order_date"
  t.datetime "created_at",            :null => false
  t.datetime "updated_at",            :null => false
end

create_table "books", :force => true do |t|
  t.integer  "publisher_id"
  t.string   "title"
  t.string   "pages"  
  t.text     "description"
  t.decimal  "price",              :precision => 8, :scale => 2
  t.date     "release_date"   
  t.datetime "created_at",         :null => false
  t.datetime "updated_at",
end

VIEWS

<% if current_user.member? %>

  <% @books.each do |book| %>

    ###Shows All Available Books
    <% if book.book_is_available %> 
      <%= book.title %>
    <% end %>

    ###Shows Books Bought By Member
    <% @orders.each do |order| %>
      <% if order.book.id == book.id %>
        <%= book.title %>
      <% end %>
    <% end %>

  <% end %>    ###I want to Subtract/Remove the Above Books from the Books Below

  ###Shows All Books Not Available or Coming Soon
  <% @books.each do |book| %>
    <%= book.book_is_not_available(book) %>
  <% end %>


<% end %>
Was it helpful?

Solution

This should work.

class User < ActiveRecord::Base
    attr_accessible :name, :email, :password, :member

    has_many :books, through: :orders
    has_many :orders, :dependent => :destroy


   def purchased_books
      books
   end
   def unavailable_unpurchased_books
      Book.unavailable.where("id Not IN ?",books.pluck(:book_id))
   end
end

class Book < ActiveRecord::Base
  attr_accessible :description, :pages, :title, :available_in, :price, :release_date

  has_many :orders
  has_many :users, through: :orders
  scope :unavailable,->{where("release_date > ?",Date.today)}
  scope :available,->{where("release_date < ?",Date.today)



end

In Controller

def index
  @available_books = Book.available
  @orders = current_user.orders
  respond_to do |format|
    format.html
    format.json  { render :json => @issues }
  end
end

In View

<% if current_user.member? %>
     ###Shows All Available Books
    <% @available_books.each do |book| %> 
      <%= book.title %>
    <% end %>

    ###Shows Books Bought By Member
    <% @orders.each do |order| %>
      <%= order.book.title %>
    <% end %>

  ###Shows All Books Not Available or Coming Soon
  <% current_user.unavailable_unpurchased_books do |book| %>
    <%= book.title %>
  <% end %>


<% end %>

Using class scopes is very useful for chaining queries unpurchased_books turns into SELECT * FROM books WHERE release_date > '2014-05-14' AND id Not IN (books the user purchased)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top