Applying what I've learned...
|
|
Eldon, I’m trying to apply what I’ve learned so far (from the Monkey and Exerciser chapter) into a hobby application that might be potentially useful to college students. The idea is that users would list textbooks that they have and textbooks that they need and the app would match them up. The difference, so far, between a wanted book vs. an offered one is “condition” of the book. How would you lay the groundwork for something like this? I’ve defined a Book model and a controller called Admin that handles listing, adding and deleting items to a list. I’ve been also toying with the idea of having two models: wantedbooks and offeredbooks with matching controllers to manipulate the models with. The view so far is simple—the page has two halves offered/want with an “add” button for each section. Each add action can call the appropriate controller, etc. But I’m worried about doing unholy things OO-wise :) I’m also seeing that I may be going down a path that is going to lead a lot of code duplication :( |
|
|
I’d probably need to think about it and sketch it out for a day or two to get a good feeling for it—but my initial thought is that it might make sense to do something like this:
So you could go from a user to any book that they want. From that book you could go back to a list of users that have the book available for. By making those associations model you can add additional information in there as well such as quality of book, number available, price willing to pay, etc Thats just off the top of my head after a few minutes of thought – so it might have a snag or two. But hopefully it helps. |
|
|
Yes, this makes sense and it validates the path (of 3 models) that I was going down… How do “Needs” and “Owns” mesh with Ruby naming conventions? A “book” model becomes “books”. Would “Needs” and “Owns” confuse things? Re: Book, Needs, Owns – can a single controller manage them all or do you see a need to have separate controllers for each? |
|
|
you can always override the table name for a model with the set_table_name method, or you could change the name of the models. The key is to look for something that makes sense and presents itself as readable as possible. What we’re doing here is trying to model the relationships between a book and a user. As for a single controller – it all boils down to a question of how close you want to keep your controllers to the CRUD ideal. There’s nothing that says that you have to create a separate controller for each model. I probably would create a controller for each of those models but that’s just me. |
|
|
OK – quick Q :) how do you add an image into a post? |
|
|
I read-up on habtm – rich topic… I wrestled with the Owns/Needs names prob more than I should have… going down set_table_name route felt like a punt… I’m not sure if the multiple “through” statement below is correct but… trying to create the “square” path in the diagram (can get to from books to users via wanted_offers and have_offers). What do you think? Class User < ActiveRecord::Base has_many wanted_offers has_many have_offers has_many books :through => wanted_offers, :have_offers end Class Book < ActiveRecord::Base has_many wanted_offers has_many have_offers has_many users :through => wanted_offers, :have_offers end Class HaveOffer < ActiveRecord::Base belongs_to :book belongs_to :user end Class WantedOffer < ActiveRecord::Base belongs_to :book belongs_to :user end Is a :dependent call needed here? since a wanted_offer or a have_offer won’t exist without a valid book… |
|
|
Trying to give you hints / nudges without just solving it for you :-) In the diagram i was more talking about it from an association point of view. Remember the goal is to model the relationship between a book and a user. So to me one way of modeling that relationship might as “ownership”. So if you were to follow that idea – an ownership model might also have a quantity field. If I user wants a book i would set that quantity to a negative number. If a user has a book but is not willing to trade it at this point then the quantity would be zero. If the user has the book and wants to trade it – then that value would be set to a positive number. Doing it this way you could also support if someone was looking to either obtain or trade multiple copies of the same book. I.e. looking to get 12 copies of a book would create an ownership record with a -12 value in the quantity. So from here you would just need to create your has_many :through associations correctly and pass in the appropriate conditions (i.e. quantity > 1) to each association. |
|
|
A nudge is always appreciated :) Let me digest the ownership and give it a try Meanwhile, I went down the road and implemented the original 4-model approach… I’m able to create a “Wanted” book, list and delete. And I’m currently wrestling with the Show and Edit. I’m a bit stuck (trying to traverse child models back to the parent, etc. which tells me that the 4-model approach my be over complicating it) :) |
|
|
PS: Can I attach a diagram to a post as u had? |
|
|
OK i think i get the “ownership” approach—see representation below. Here is the matching algorithm I am thinking of … it seems like want/have should be tracked separately (as objects?). Nudge me :)
Class User < ActiveRecord::Base has_many :ownerships has_many :books :through => :ownerships end Class Book < ActiveRecord::Base has_many :ownerships has_many :users :through => :ownerships end Class Ownership < ActiveRecord::Base belongs_to :user belongs_to :book end |
|
|
Textile just has you put exclamation marks before and after the url to the image |
|
|
Heres one last nudge… :-) class Ownership < ActiveRecord::Base belongs_to :user belongs_to :book end class Book < ActiveRecord::Base has_many :ownerships has_many :needs, :through => :ownerships, :source => :user, :conditions => 'quantity < 0' has_many :owns, :through => :ownerships, :source => :user, :conditions => 'quantity > 0' end class User < ActiveRecord::Base has_many :ownerships has_many :needs, :through => :ownerships, :source => :book, :conditions => 'quantity < 0' has_many :owns, :through => :ownerships, :source => :book, :conditions => 'quantity > 0' end Now those models aren’t complete so you’ve still got a little work to do on your own (one more hint – think about making sure that there is only one row in the ownership table for a given book and user). But once you get this going you’ll be able to simply calls owns and needs on a user object to collect a list of book that that user has or is looking for. Just build it out and play around with it in script/console—adding users / books and ownerships and modifying the models as needed until you get it. Playing around with it is the best way to learn. |
|
|
Couple of good resources for learning more about how to use has_many :through Josh Susser has blogged about them numerous times over the years at his blog I can’t remember 100%, but I think they were covered in RailsEnvy’s screencast on ActiveRecord |
|
|
Much to digest |
|
|
Quick update – i just went through the sources you posted – a wealth of good stuff. I’m letting the stuff settle into my gray matter before I take a dive and build out what you started… I hope to make you proud Sensei :) |
|
|
I’ve been going through these screencasts and they are incredibly useful (the relaxed style of the authors is very calming). I’m wondering if Eldon or others have come across other railcasts that you’d like to share. PS: I’m getting back to the project in this thread (got hit by the flu for a couple of days). |
|
|
Yeh, Railscasts rock. Ryan Bates does an awesome job of explaining everything. You feel like just you’ve just spent a day at relaxation-health-spa after each screencast! |
|
|
I hate to admit it but i stay up until 2am every sunday night just so I can check out the newest RailsCast. But I’m also a night-owl and more than a bit obsessive. Some of my first pure ruby scripts (i.e non-rails) were scripts that would load a page on the some book publishers websites and immediately notify me if a book I was waiting for was available for purchase now (that site didn’t have an RSS feed back then). For other screencast goodness – there’s also Peepcode.com which I’m sure you’ve seen reference to from the RailsCasts. Rubyplus.org is a new site that recently started Ruby and Rails screencasts, I’ve only downloaded two of those so far but the audio had issues to where it was a real pain to make out what he was saying so I haven’t been back. Maybe they’re fixed now. |
|
|
Rails Envy podcasts are also worth checking out. I have smile on my face the whole time I’m listening to them, which is usually while I’m stumbling round for a bowl-cereal-milk combination. |
