views:

66

answers:

2

I am creating a system where a user can select any combination of four options.

Then results are displayed based on their exact combination.

For example, if a user chose color, text, and logo. Only results featuring color, text, and logo would return.

On the other side, I am creating "templates" that will eventually be the results returned. Each template will be earmarked to be able to return properly when a user selects a combination that corresponds with the template.

My Question :

What is the best way to categorize this information in the back-end so it can be pulled by the user requests?

For example, I have a template that can be color and text OR color, text, and logo. My guess is two group these two in a family, and then when a combination is made, a query reviews each family for a matching combo; if true, that specific combo variation is returned.

Would you do it any differently?

Thanks!

+1  A: 

You shoudn't hardcode the number of available categories (what if tomorrow you need another category?)

Combination
  has_many :categories
  belongs_to :template

  def self.find_by_selected_categories(array_of_categories)
    self.find(:first, :conditions => {:categories => array_of_categories})
  end
end

Template
  has_many: combinations
end

...

The downside of this approach is that you must have a correspondence table (categories-combinations).

Vlad Zloteanu
+1  A: 

This is a fairly complicated problem description. I'm having a little trouble parsing some of it -- e.g. "when a combination is made" -- in the absence of a real thing to look at. (And what does it have to do with storing images? Are your templates images?)

That said... I'd say the simplest approach is to handle your searching as a Rails task rather than a data task. Just set whatever attributes you need for your Template model:

# In the migration
create_table templates do |t|
  t.string   :color  # Set a validation for your hex codes, or whatever, in Rails
  t.string   :text
  t.string   :logo_file_name    # These all assume you're using the Paperclip gem.
  t.string   :logo_content_type # (http://thoughtbot.com/projects/paperclip)
  t.integer  :logo_file_size    # If you're tracking your logo attachment some other
  t.datetime :logo_updated_at   # way, do whatever's needed in that case.
end

Then, in the model, set named scopes for the various options:

class Template < ActiveRecord::Base
  has_attached_file :logo

  named_scope :with_color, :conditions => {"color is not null"}
  named_scope :with_text, :conditions => {"text is not null"}
  named_scope :with_logo, :conditions => {"logo_file_name is not null"}
  # You could add :without_ named scopes too, of course, if you needed them
end

Then you can simply chain them together to match whatever the user checked in their search, e.g. Template.with_color.with_text.with_logo and you'll get whatever survives at the end of the named scope filtering.

Does that make sense? Named scopes are very handy for this sort of thing -- you might want to Google on them if you haven't come across them before.

SFEley