gpt4 book ai didi

ruby-on-rails - 验证多态亲本的存在

转载 作者:行者123 更新时间:2023-12-03 22:33:48 27 4
gpt4 key购买 nike

我正在开发具有以下模型的 Rails 3.2 应用程序:

class User < ActiveRecord::Base
# Associations
belongs_to :authenticatable, polymorphic: true

# Validations
validates :authenticatable, presence: true # this is the critical line
end

class Physician < ActiveRecord::Base
attr_accessible :user_attributes

# Associations
has_one :user, as: :authenticatable
accepts_nested_attributes_for :user
end

我想要做的是验证用户是否总是有一个可验证的父级。这本身工作正常,但在我的表单中,用户模型提示不存在可验证的。

我正在使用以下 Controller 为新医生显示一个表单,该表单接受用户的嵌套属性:
def new
@physician = Physician.new
@physician.build_user

respond_to do |format|
format.html # new.html.erb
format.json { render json: @physician }
end
end

这是我的创建方法:
def create
@physician = Physician.new(params[:physician])

respond_to do |format|
if @physician.save
format.html { redirect_to @physician, notice: 'Physician was successfully created.' }
format.json { render json: @physician, status: :created, location: @physician }
else
format.html { render action: "new" }
format.json { render json: @physician.errors, status: :unprocessable_entity }
end
end
end

在提交表单时,它说用户的身份验证不能为空。但是,authenticable_id 和authenticate_type 应该尽快分配 @physician被保存。如果我使用相同的表单来编辑医生及其用户,它工作正常,因为从那时起分配了 id 和类型。

我在这里做错了什么?

最佳答案

我相信这是预期的:
https://github.com/rails/rails/issues/1629#issuecomment-11033182 (最后两条评论)。
也可以从 rails api 中查看此内容:

One-to-one associations

Assigning an object to a has_one association automatically saves thatobject and the object being replaced (if there is one), in order toupdate their foreign keys - except if the parent object is unsaved(new_record? == true).

If either of these saves fail (due to one of the objects beinginvalid), an ActiveRecord::RecordNotSaved exception is raised and theassignment is cancelled.

If you wish to assign an object to a has_one association withoutsaving it, use the build_association method (documented below). Theobject being replaced will still be saved to update its foreign key.

Assigning an object to a belongs_to association does not save theobject, since the foreign key field belongs on the parent. It does notsave the parent either.


和这个

build_association(attributes = {}) Returns a new object of theassociated type that has been instantiated with attributes and linkedto this object through a foreign key, but has not yet been saved.


您必须先创建一个父级。然后将它的 id 分配给多态对象。
据我所知,您创建了一个对象 Physician.new 来构建 User,但此时它尚未保存,因此它没有 id,因此没有什么可分配给多态对象。所以验证总是会失败,因为它在保存之前被调用。
换句话说:在您调用 build_user 的情况下,它返回 User.new NOT User.create 。因此authenticatable 没有分配authenticateable_id。
您有多种选择:
  • 先保存关联用户。
    或者
  • 将验证移至 after_save 回调(可能但非常烦人和糟糕)
    或者
  • 更改您的应用程序结构 - 也许避免多态关联并通过切换到 has_many?我很难判断,因为我不了解内部结构和业务需求。但在我看来,这不是多态关联的好选择。除了 User 之外,您是否还有更多可验证的模型?

  • 恕我直言,多态关联的最佳候选者是电话、地址等。地址可以属于用户、客户、公司、组织、Area51 等,可以是家庭、运输或账单类别,即它可以 变形 以适应多种用途,因此是一个很好的提取对象。但是 Authenticatable 在我看来有点做作,并在不需要它的情况下增加了复杂性。我没有看到任何其他需要可验证的对象。
    如果您可以展示您的 Authenticatable 模型和推理以及迁移(?),我可以为您提供更多建议。现在我只是凭空想出这个 :-) 但它似乎是重构的好候选者。

    关于ruby-on-rails - 验证多态亲本的存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14553463/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com