Как получить доступ к родительскому объекту при построении объекта через вложенный синтаксис в Rails - PullRequest
0 голосов
/ 22 февраля 2019

Я сталкиваюсь с текущей проблемой.У меня есть процессор Paperclip, которому требуется доступ к существующим атрибутам родительского объекта при использовании вложенного синтаксиса parent.children.create(file: File).Я знаю, что могу использовать

child = parent.children.new
child.file = file
child.save

и таким образом иметь доступ к родителю, но, поскольку я нахожусь в большом проекте и имею parent.children.create по всему проекту, было бы лучше, если бы я мог найтирешение для исходной задачи.

Мой анализатор:

class Paperclip::Processors::ChildFileParser < ::Paperclip::Processor
  def make
    if @attachment.instance.parent.parent_attribute
      begin
        some_logic
      rescue => e
        Rails.logger.error("error")
      end
    end
    Paperclip::TempfileFactory.new.generate
  end
end

Так что при попытке доступа к @attachment.instance.parent.parent_attribute в операторе if он выдаст ошибку there is no parent_attribute for nil.Приведенный выше метод выполняется при построении дочернего объекта.

Редактирование 1:

Просто добавление отношения.

class Parent
  has_many :children, class_name: 'Child'
end

class Child
  belongs_to :parent
end

1 Ответ

0 голосов
/ 22 февраля 2019

Я не совсем уверен, что это то, что вам нужно, хотя работа с приведенным кодом позволит избежать NoMethodError с которыми вы столкнетесь.Если родитель существует, вы сможете получить к нему доступ даже при использовании build / create.EG

c = parent.build_child
c.parent # => #<Parent id: ...>

Следовательно, как насчет одного из следующих:

 # ref https://api.rubyonrails.org/classes/Object.html#method-i-try
if @attachment.instance.parent.try(:parent_attribute)
  ...
end

# ref https://docs.ruby-lang.org/en/2.6.0/syntax/calling_methods_rdoc.html#label-Safe+navigation+operator
if @attachment.instance.parent&.parent_attribute 
  ...
end

# both use safe navigation operators and are essentially short hand for:
# @attachment.instance.parent && @attachment.instance.parent.parent_attribute

Они вернут nil, если нет родителя, и поэтому будут ложными, чтобы перейти к Paperclip::TempfileFactory.new.generate.

Вы также можете использовать delegate:

# child.rb
delegate :parent_attribute, to: :parent, allow_nil: true

Это позволит вам безопасно звонить:

if @attachment.instance.parent_attribute
  # ...
end

NBВы также можете предоставить префикс для делегирования, если он помогает уточнить вещи при вызове метода на @attachment.instance.

Надеюсь, что это поможет - дайте мне знать, как у вас обстоят дела или если у вас есть какие-либо вопросы.

...