Topic: Help identify resources

So I was thinking of creating a directory app.

These would be the fields:

Main City (City model)
Neighborhood (Neighborhood model)
Company
Address
City
State
Zip
Category (Category Model |aat| )
Subcategory (Category Model |aat| )
Tags (Tag model)

I dont know what's the best way to implement this?

Any thoughts?

=====================
Sam G.

Re: Help identify resources

Are you sure you need both categories and tags?  It's often the case that folks go with one or the other.  It's not important that you choose one, but I thought I'd recommend it.

Here's the structure I recommend:

City
  has_many :neighborhoods
Neighborhood
  belongs_to :city
  has_many :listings
State
  has_many :zips
Zip:
  belongs_to :state
Listing
  belongs_to :neighborhood
  belongs_to :zip
  # columns: company, address

Re: Help identify resources

Your listings model can look like this to help you find the state and city:

class Listing < ActiveRecord::Base
  belongs_to :neighborhood
  belongs_to :zip

  def city
    neighborhood.city
  end
 
  def state
    zip.state
  end
end


You can find a complete list of zipcodes out there if you Google around.  Some even have latitude and longitude to you can do easy distance calculation between two points based on the zipcode.

Re: Help identify resources

Oh wow neat that didn't even occur to me with the zip but thats awesome. Eventually, I want to be able to tie it up with some mapping capability and your input leads me to that exactly.

With regards to the category and tags, that would have to be a yes on both.

Is it possible to map this model relationship as city/category/subcategory/:id?

=====================
Sam G.

Re: Help identify resources

you mean, to map it that way in the url? Sure!

The simplest way would be to specify the following in your routes.rb:

map.full_listing ":city/:category/:subcategory/:id"

You'd use it like this:
<%= full_listing_path(:city => @listing.city, :category => @listing.category, :subcategory => @listing.subcategory, :id => @listing.id)

It's a little cumbersome that way - but I'm sure you could find way to trim that down if you played around :-)

Also, might I suggest using the to_param method on your Listing model so the :id is something other than the database id?  It's a handy way to SEO-ify your Rails app.  You can have your model use a url-ized version of the business name rather than an arbitrary number.
http://api.rubyonrails.org/classes/Acti … ml#M001036

Good luck!

Re: Help identify resources

Sorry, just an ror noob here trying to get around. I am not exactly sure how to_param works. But I'll be researching on it. Unfortunately, the api really has nothing much on it. An example would be nice.

to_param() leads me to believe based on the short desc that I can eventually do city/category/subcategory/company_name?

=====================
Sam G.

Re: Help identify resources

Yeah, sorry about the docs.  Sometimes I forget just how Spartan they are.

When you do this:
<%= url_for(:action => 'show', :id => @listing) %>
What this really translates into is:
<%= url_for(:action => 'show', :id => @listing.to_param) %>
So by creating a to_param method on your model you can change what shows up in the url.

Here's the gotcha: You have to be able to find the record based on what shows up in the url.  So it's up to you to make sure you're saving an attribute that has the kind of meaningful text you want but is absolutely unique in it's table.

One way to do it:

# this assumes you've got a string column in your 'listings' table called 'param'
class Listing < ActiveRecord::Base
  before_save :set_param

  def to_param
    param
  end

  protected

    def set_param
      self.param = "#{id}_#{business_name.downcase.gsub(' ','_')}"
    end
end

# you'd retrieve it with:
@listing = Listing.find_by_param(params[:id])


That's all there is to it!

Re: Help identify resources

Can you explain to me what this code mean and how it was formed that way from the listing.rb?

def city
  neighborhood.city
end
   
def state
  zip.state
end

Thanks.

Last edited by shajused (2007-05-24 07:43:13)

=====================
Sam G.

Re: Help identify resources

Sure, that's just a shortcut.  You don't want to save the city data in both the neighborhood model and the listing model - then you'd have it spread in two places.  That's really hard to maintain and there's no way to ensure that you don't one day get those two pieces of city data our of sync (like, if a listing in san francisco gets messed up and is re-filed under NY - but the listing's neighborhood is still filed under san francisco).

So the code that I posted is just an easy way to ask "what's the city related to this listing?" without having to save city data in the 'listings' table of the database.  Instead, you just walk along the chain of has_many and belongs_to's until you find the right piece of information.

Really it's unnecessary - you could just do Listing.find(6).neighborhood.city but Listing.find(6).city saves some hassle.

Re: Help identify resources

Thanks for the explanation.

What if I wanted to add categorization to listing where categories has these fields:

#Category Migration
t.column :categories, :name, :string
t.column :categories, :parent_id, :integer

and I wanted to add the above as an acts_as_tree too to the listing model:
#Listing Migration
add_column :listings, :category_id, :integer
add_column :listings, :subcategory_id, :integer

If its acts_as_tree , then is it habtm or just a plain has_many?
# Category 
class Category < ActiveRecord::Base
has_many listings
end
# Listing
class Listing < ActiveRecord::Base
belongs_to categories
end

Thanks for the help. I'm just trying to master associations and I'm confusing myself sometimes.

=====================
Sam G.

Re: Help identify resources

I think you're really on the right track!

Three (small) changes:
1) You'll want to remove the subcategory_id field from listings - you just need category_id.  Just set the category of the listing to the lowest subcategory that you want it attached to.  You can always lookup the parent categories later.
2) it should be 'belongs_to :category' - category should be singular 'cause a listing will only have one category (directly, at least).
3) make sure to say :listings rather than listings in a has_many or belongs_to

With the schema (database structure) that you provided you'll be able to do something like this:

@listing = Listing.find(3)
@listing.category # => 'Lawnmower Repair'
@listing.category.parent # => 'Equipment Repair'
@listing.category.parent.parent # => 'Technical Services'
# etc.

That's a pretty clean structure and it should allow you to change things easily in the future.

Re: Help identify resources

Thanks, Jack.

The administration of Categories with regards to hierarchy will then be in the Category resource and not in Listing. OK, that makes sense.

So far so good.

=====================
Sam G.