одна модель имеет два столбца вложенных файлов - Rails 4 + Paperclip - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть пользовательская модель, которая использует модель крепления в рельсах. Моя модель вложения выглядит примерно так

class Attachment < ActiveRecord::Base
  belongs_to :attachable, polymorphic: true
  has_attached_file :file, styles: { logo: ['200x50>',:png] }
end

, а другая модель, которая использует вложение, выглядит примерно так

class User < ActiveRecord::Base
  has_many :attachments, as: :attachable, dependent: :destroy
end

Я хочу, чтобы пользовательская модель имела другое вложение, отличное от того, которое я уже настроил для загрузки логотипа, что-то вроде этого

has_one :user_logo, -> {where attachable_type: "UserLogo"}, class_name: "Attachment", foreign_key: :attachable_id, foreign_type: :attachable_type, dependent: :destroy

но когда я пытаюсь получить доступ к attachment.attachable, я получаю

undefined UserLogo as **UserLogo** is not a model.

Может кто-нибудь предложить, какие изменения я могу сделать, чтобы attachment.attachable работал для обоих типов вложений.

так например

когда я выполняю что-то вроде этого

att = Attachment.find(3) # предполагается, что он возвращает присоединяемый тип как пользователь Поэтому att.attachable возвращает объект пользователя

но когда я выполню att = Attachment.find(3) # предполагается, что он возвращает присоединяемый тип как UserLogo так att.attachable возвращает исключение wrong constant name UserLogo

как я могу получить доступ к User объекту из обоих типов вложений. Спасибо

1 Ответ

0 голосов
/ 20 ноября 2018

Держите ваш присоединяемый тип «Пользователь», который будет чистым полиморфным. Определите поле type внутри модели «Вложение», имеющее два значения logo & file

Ассоциация будет обновляться как показано ниже

class User < ActiveRecord::Base

has_many :attachments, -> {where type: "file"}, as: :attachable, dependent: :destroy  
has_one :user_logo, -> {where type: "logo"}, class_name: "Attachment", foreign_key: :attachable_id, foreign_type: :attachable_type, dependent: :destroy

end

Я предлагаю вам иметь разные стили для прикрепления, в зависимости от того, какой у него тип (логотип / файл). Проверка для типа вложения также зависит от типа.

has_attached_file :file, styles: ->(file){ file.instance.get_styles }

validates_attachment_content_type :file, :content_type: [..], if: -> { type == 'logo' }

validates_attachment_content_type :file, :content_type: [..], if: -> { type == 'file' }


def get_styles
  if self.type == 'logo'
    style1
  elsif self.type == 'file'
    style2
  end
end

Пожалуйста, обновите статус или любой запрос, который вы получите.

Обновление - ответ на следующий вопрос

Первый способ: Если вы используете UserLogo в качестве присоединяемого_типа в Attachment, тогда он не следует полиморфной ассоциации, поэтому определите пользовательскую ассоциацию.

belongs_to :resource,
  -> { |attachment| ['User', 'UserLogo'].include? attachment.attachable },
  class_name: 'User',
  foreign_key: :attachable_id

belongs_to :belongs_to :attachable,
  -> { |attachment| ['User', 'UserLogo'].exclude? attachment.attachable_type },
  class_name: :attachable_type,
  foreign_key: :attachable_id

Второй способ: Создать UserLogo расширение класса User класс. Он найдет UserLogo с теми же данными пользователя

...