Как правильно реализовать ассоциацию?
Как вариант, для Age параметра заведите поле Active Record Enum. Примерно так:class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end
Теперь можно с моделью делать так:# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status  # => "active"
 
# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status    # => "archived"
 
# conversation.update! status: 1
conversation.status = "archived"
 
# conversation.update! status: nil
conversation.status = nil
conversation.status.nil? # => true
conversation.status      # => nil
 
#Автоскоупы модели для выборки по енум полю
Conversation.active
Conversation.archived
Пример миграции для создания поля:create_table :conversations do |t|
  t.column :status, :integer, default: 0
end
1. Про семантику. Не возраст обладает продуктами, а:
* Продукт может предназначаться для такого-то возраста
* Для такого-то возраста имеются такие-то продукты
2. Целесообразность использования отдельной модели Age. Вам точно нужна отдельная таблица? 
* Можно завести отдельное поле в табличные projects типа string.
* Можно завести поле типа json\hstore для разнообразных подобных справочников. Может пригодиться https://github.com/jalkoby/active_store_accessor
Выборка по подобным полям так же возможна:scope :for_age, ->(age){ where(%q{"hstore_field"->'age' = '?'}, age) }
3. Если все же хотите использовать модель для age, то удобно делать так:class Product
  belongs_to :product_age, class_name: Age.name
  delegate :age, to: :product_age
end