Задать вопрос

Как правильно реализовать ассоциацию?

Здравствуйте!

Есть модель Product у которой есть только один параметр, например age который берется из записи соответствующей модели Age, но этот параметр может также принадлежать и другой модели.

Записи модели Age из которых берется параметр для модели Product
Age.all
id: 1, name: "Взрослый"
id: 2, name: "Юниор"
id: 3, name: "Детский"


Сейчас все реализовано через связь belongs_to:
class Product
	belongs_to :age
	...
end


Схема таблицы Products
create_table "products", force: :cascade do |t|
    t.integer  "age_id"
    ....
end


Такое решение работает, но меня смущает семантика такой связи, как например может возраст обладать продуктом? Или само решение в корне не верно?

Помогите пожалуйста!
  • Вопрос задан
  • 196 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 2
railsfun
@railsfun
Web Developer
Как вариант, для 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
Ответ написан
Комментировать
@CorbenDallass
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
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы