首页 > 解决方案 > 创建记录时,从关联记录中复制属性

问题描述

在我的 Rails 待办事项应用程序中,我有一个 Tasks 模型。任务可以是blocked_by彼此的。每个任务都有一个用户。当我这样做时taskA.blocked_by.create(name: "Task B"),我希望任务 B 获得与任务 A 相同的用户。

问题是,我不知道如何引用创建当前记录的记录。我需要学习如何获取taskA.user,以便我可以自动将其分配给taskB. 我宁愿每次创建blocked_by 任务时都不必手动执行此操作。

我试过设置self.user一个before_validation方法。

before_validation :inherit_user, on: :create

private
    def inherit_user
        if self.user == nil 
            p "Task #{self.name} missing user"
            if self.blocked_by.count > 0
                self.user = self.blocked_by.first.user
                p "Inheriting user from first blocked_by task #{self.blocked_by.first.name}"
            end
        end
    end

这不起作用,self.blocked_by因为记录尚未保存,因此为空。

Rails 关于关联类方法的文档让我相信我应该能够做这样的事情:

has_many :blocked_by do |owner|
    def create(attributes)
        p owner # access properties from association owner here
        attributes.push(user: owner.user)
        super
    end
end

当我尝试这个时,我得到:

NoMethodError (undefined method `owner' for #<ActiveRecord::Associations::CollectionProxy []>)

编辑:这是我的模型文件:

class Task < ApplicationRecord
    validates :name, :presence => true

    belongs_to :user

    has_many :children, class_name: "Task", foreign_key: "parent_id"
    belongs_to :parent, class_name: "Task", optional: true
    has_ancestry

    # thanks to https://medium.com/@jbmilgrom/active-record-many-to-many-self-join-table-e0992c27c1e
    has_many :blocked_blocks, foreign_key: :blocker_id, class_name: "BlockingTask"
    has_many :blocked_by, through: :blocked_blocks, source: :blocking, dependent: :destroy

    has_many :blocker_blocks, foreign_key: :blocked_id, class_name: "BlockingTask"
    has_many :blocking, through: :blocker_blocks, source: :blocker, dependent: :destroy

    has_many_attached :attachments

    before_validation :inherit_user, on: :create

    def completed_descendants
        self.descendants.where(completed: true)
    end

    def attachment_count
        self.attachments.count
    end

    private
        def inherit_user
            if self.user == nil and self.parent
                self.user = self.parent.user
            end
        end

end

我可以inherit_user从父任务中,像这样:taskA.children.create(name: "Task B")。我想为一段blocked_by关系做同样的事情。

标签: ruby-on-rails

解决方案


要引用应该创建的当前记录,请尝试运行before_create回调。

 before_create :inherit_user

现在self.blocked_by必须有一个值。


推荐阅读