【问题标题】:Updating child-records with their parents' attrs on create?在创建时使用父母的属性更新子记录?
【发布时间】:2012-01-10 18:44:12
【问题描述】:

在 Rails 中,如何在子记录或父记录保存之前使用其父记录的值更新子记录?

我正在使用 Rails 的嵌套属性来创建包含许多子项的父记录。父记录有一个 user_id 属性来跟踪其所有者,出于本问题范围之外的目的,子记录需要存储此 user_id 属性。

目前,我在子模型上使用 before_save 回调:

before_save   :set_user_id

def set_user_id
  if user = self.parent.try(:user) 
    self[:user_id] = user.id
  end
end

但是因为我还需要确保孩子对于给定的父/用户组合是唯一的,所以我必须这样做:

validates :parent, 
          :uniqueness => {:scope => :user_id}, 
          :unless => Proc.new{|child| child.user_id.blank?}

问题在于unless 参数。孩子的 user_id attr 在验证之前是空白的,因此验证不会在孩子创建时有效地运行。如果用户重复提交表单,这会导致问题;结果是重复的、无效的订阅最终出现在数据库中。我试图通过改变这个来解决这个问题:

before_save   :set_user_id

before_validate   :set_user_id

但在验证之前似乎无法访问父级的 user_id。

有人遇到过这样的问题吗?

【问题讨论】:

  • 只是为了澄清:父母可能没有有用户?这就是self.parent.try(:user) 告诉我的,但你没有在你的问题中提到它
  • @Delba 否,这意味着父级可能为零
  • @ThongKuah 嗯,这基本上是一样的......只是想得到提问者的确认,因为它会影响答案。
  • @Delba,不,父母存在并且有一个用户。所以可以改写为self.parent.user
  • @trisignia 我已经在 3.0.x 项目上尝试过代码,在 before_validation 中,子级可以使用父级和父级的属性。而且,如果父级也是新的,您仍然会得到一个副本,因为 parent_id 总是不同的。如果父母已经存在,似乎孩子总是只能拥有来自父母的 user_id。如此有效,这将每个父母的孩子人数限制为一个?

标签: ruby-on-rails validation activerecord associations nested-attributes


【解决方案1】:

如果可能的话,你能在表单中放置一个带有 user_id 的隐藏字段吗?您可能需要在 after_save 中进行一些验证和可能的回滚,但这似乎很容易。

另一个选项可能是在调用父对象的保存/创建之前,在控制器的 params 哈希中为所有相关对象设置 user_id。

【讨论】:

    猜你喜欢
    • 2017-08-18
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多