Настройте мою модель так, чтобы поле могло ссылаться на множество различных типов классов - PullRequest
1 голос
/ 29 марта 2012

Допустим, у меня есть модель Company и модель Product, обе из которых связаны с UserUploadedImage. Я хочу создать свой UserUploadedImage таким образом, чтобы я мог написать image.parent, и это будет ссылаться либо на Product, либо на Company, в зависимости от того, что подходит в этом случае.

Я понимаю, что могу хранить второй столбец в UserUploadedImage с Product или Company и иметь условное выражение для поиска подходящего значения. Я, однако, не уверен, где находится оптимальное место для размещения этого кода или есть более чистый способ достижения моей цели. Спасибо!

1 Ответ

3 голосов
/ 29 марта 2012

Что вам нужно посмотреть, так это Полиморфные Ассоциации

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Полиморфные ассоциации

Несколько более сложный поворот ассоциаций - это полиморфная ассоциация. При полиморфных ассоциациях модель может принадлежать нескольким другим моделям в одной ассоциации. Например, у вас может быть модель изображения, которая принадлежит либо модели сотрудника, либо модели продукта.

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

class Employee < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

Вы можете думать о полиморфном объявлении own_to как о настройке интерфейса, который может использовать любая другая модель. Из экземпляра модели Employee вы можете получить коллекцию изображений: @employee.pictures.

Аналогичным образом вы можете получить @product.pictures.

Если у вас есть экземпляр модели Picture, вы можете получить его parent через @picture.imageable. Чтобы это работало, вам нужно объявить как столбец внешнего ключа, так и столбец типа в модели, которая объявляет полиморфный интерфейс:

class CreatePictures < ActiveRecord::Migration
  def change
    create_table :pictures do |t|
      t.string  :name
      t.integer :imageable_id
      t.string  :imageable_type
      t.timestamps
    end
  end
end

Эту миграцию можно упростить, используя форму t.references:

class CreatePictures < ActiveRecord::Migration
  def change
    create_table :pictures do |t|
      t.string :name
      t.references :imageable, :polymorphic => true
      t.timestamps
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...