views:

77

answers:

2

Im modeling an online book with ruby on rails. The book has chapters, each chapter has pages. Modeling this part is easy. What id like to do is keep track of what pages each user has read and when and whether they liked that page / whether the user completed the book. How would one recommend modeling keeping track of this in rails? Id ideally like to say give me all the books the user is or has read, and then have access to the book plus state info for that user's reading of the book.

A: 

The BookState becomes the intermediate object between the user and the book.

class User < ActiveRecord::Base
   has_many :book_states
   has_many :books, :through => :book_state
end

class BookState < ActiveRecord::Base
   belongs_to :user
   belongs_to :book
end

class Book < ActiveRecord::Base
   has_many :book_states
end

BookState has the current location, the likes/dislikes, etc. If you ask for a user's bookStates, that will give you the books as well.

JacobM
Hey Jacob, Thanks for the quick reply. But what if we are keeping track of hte user reading specific pages (some pages they read, some they skip) and we want to be able to present them with a copy of the book displaying which pages / sections are read / skipped. Would we instead of using BookState use PageState? This seems like it presents a whole set of issues though.
Lee
I'd model the page state as a hash within the book state.
JacobM
and then manually fill in / draw the states on top of the model, as opposed to having a logical relationship between the page state and the actual page itself?
Lee
Yeah, maybe have some kind of BookRenderer helper that "filters" the book based on the hash of pagestate, etc.
JacobM
This way the pagestate thing is less tied to the internal representation of the book, which you may want to change.
JacobM
Jacob i posted a response below (it was too long to fit in this comment)
Lee
A: 

This makes a lot of sense. The one problem i see is collecting stats on a question (what percent of the time was this answered)? Since that data is in serialized hashes? What about this:

book
    has_many user_books
 has_many users through user_books
 has_many chapters

chapter
 belongs_to book
 has_many pages

page
 belongs_to chapter
 has_many user_pages

user
    has_many user_books
 has_many books through user_books

user_book
 belongs_to user
 belongs_to book
 has_many user_pages

user_page
 belongs_to user_book
 belongs_to page

What do you think?

Lee
Sure, that seems like it would work. How would you indicate the order of the pages within a chapter?
JacobM
good catch, page will have to have an order variable. thanks again for everything Jacob.
Lee