asdfkjasdfjk
asdfkjasdfjk

Reputation: 3904

How to make active record association for multiple categories and sub-categories with products/ads

I am trying to understand the model design for classified ads. Suppose I have some category and sub category under it like below

Electronics(Main category)
-Mobile
--Company
---Model
-TV
--Company
---Model
Property(Main category)
-Car(Sub category)
--Brand(Sub Sub category)
---Speed Range(Sub Sub Sub category)

And I have a model for Ads.

How can I make the relationship among the categories, all sub categories and ads. So far I have come up with the design below

class MainCategoy < ActiveRecord::Base
  has_many :subcategory
end

class SubCategoy < ActiveRecord::Base
  has_many :subsubcategoy 
  belongs_to: maincategory
end

class SubSubCategoy < ActiveRecord::Base
  has_many :subsubsubcategory
  belongs_to: subcategory
end

class SubSubSubCategoy < ActiveRecord::Base
  belongs_to: subsubcategory
end

class Ads< ActiveRecord::Base

end

Now my question is (1) is my association for different category and subcategories correct? If not please suggest what would be best design.

(2) I don't understand how to associate ads with category and subcategory. It is not necessary that a Category will always have a SubSubSubCategory or SubSubCategory but it will must have SubCategory. How can I do the association for this?

Upvotes: 2

Views: 852

Answers (3)

IngoAlbers
IngoAlbers

Reputation: 5812

You could just use one self-referential model, for example like this:

class Category < ActiveRecord::Base
  has_many :child_categories, class_name: "Category", foreign_key: "parent_category_id"
  belongs_to :parent_category, class_name: "Category", foreign_key: "parent_category_id"
end

Here you would use the field parent_category_id to specify the parent category when there is one. This would basically provide you with a tree structure of categories.

Then you can also easily associate ads only to this model. For example if you want to have a many to many association, you would add this to the category model:

has_and_belongs_to_many :ads

And then for the ads model:

class Ads < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

See also http://guides.rubyonrails.org/association_basics.html on how to set up the migrations.

As one ad can only belong to one category you can set up the associations like this:

class Category < ActiveRecord::Base
  has_many :child_categories, class_name: "Category", foreign_key: "parent_category_id"
  belongs_to :parent_category, class_name: "Category", foreign_key: "parent_category_id"

  has_many :ads
end

class Ads < ActiveRecord::Base
  belongs_to :category
end

You should also read the rails association basics guide I linked earlier. It has all relevant information and will help you to easily set up the models and associations.

Upvotes: 1

Florin Ionita
Florin Ionita

Reputation: 271

Set up a parent-child relationship for the same model

ad :parent_id to Category

class Category < ActiveRecord::Base
  belongs_to :parent, class: Category
  has_many :subcategories, class: Category, foreign_key: :parent_id
  has_many :subsubcategories, class: Category, through: :subcategories, source: :subcategories

  has_many :ads

end

Upvotes: 0

Alexander Shlenchack
Alexander Shlenchack

Reputation: 3869

First at all, for tree-structure data you can use awesome_nested_set or others. There you can do many nifty things with your data structures, like this (with single query to DB):

Category.each_with_level(Category.root.self_and_descendants) do |category, level|
  ...
end

And for Ads I would use has_and_belongs_to_many association:

class Ads< ActiveRecord::Base
  has_and_belongs_to_many :categories
end

Or simple use array field (Postgresql):

add_column :ads, :integer, array: true, default: '{}'

Upvotes: 0

Related Questions