通过Rails中的嵌套语法构建对象时如何访问父对象

时间:2019-02-22 11:19:21

标签: ruby-on-rails associations paperclip

我正在面对当前的问题。我有一个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 :(得分:0)

我不完全确定这是您要追求的,尽管使用给定的代码可以避免遇到NoMethodError。如果父级确实存在,即使使用build / create,您也应该能够从子级访问它。例如

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

如果在@attachment.instance上调用方法时有助于澄清事情,则还可以提供一个委托前缀。

希望有帮助-让我知道您的生活状况或有任何疑问。