验证多态性父presence [英] Validate presence of polymorphic parent

查看:166
本文介绍了验证多态性父presence的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个Rails 3.2的应用程序有如下型号:

I am developing a Rails 3.2 application with the following models:

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

我所试图做的是验证用户是否总是有一个可验证的父母。这工作得很好本身,但在我的形式向用户模式抱怨所述可验证不是present。

What I am trying to do is validate whether a user always has an authenticatable parent. This works fine in itself, but in my form the user model complains that the authenticatable is not present.

我使用下面的控制器来显示它接受嵌套属性为用户的新医生的表单:

I am using the following controller to show a form for a new physician which accepts nested attributes for the user:

def new
  @physician = Physician.new
  @physician.build_user

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

这是我创建的方法:

And this is my create method:

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

在提交表单,它说用户的可验证不能为空。然而,authenticatable_id和authenticatable_type应尽快指定为 @physician 保存。如果我用同样的形式编辑医生和其用户,自那时以来,该ID和类型分配它工作正常。

On submitting the form, it says that the user's authenticatable must not be empty. However, the authenticatable_id and authenticatable_type should be assigned as soon as @physician is saved. It works fine if I use the same form to edit a physician and its user, since then the id and type are assigned.

我在做什么错在这里?

推荐答案

我相信这种预期:

<一个href=\"https://github.com/rails/rails/issues/1629#issuecomment-11033182\">https://github.com/rails/rails/issues/1629#issuecomment-11033182 (最后两个注释)。

https://github.com/rails/rails/issues/1629#issuecomment-11033182 ( last two comments).

也检查了这一点,从导轨API

一to-one关联

分配一个对象到HAS_ONE协会自动保存
  对象和被替换的对象(如果有的话),以
  更新外键 - 除非父对象未保存
  (new_record?==真)。

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

如果任一这些节省失败(该对象由于一个是
  无效),一个ActiveRecord :: RecordNotSaved引发异常和
  分配被取消。

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

如果你希望一个对象分配给HAS_ONE无关联
  保存,使用build_association方法(下面介绍)。该
  被替换的对象仍然会被保存,以更新其外键。

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

分配一个对象到belongs_to的关联不保存
  对象,因为外键字段属于父。它不是
  救母无论是。

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

build_association(属性= {})返回一个新对象
  已实例化的属性和链接相关联的类型
  通过外键这个对象,但尚未保存。

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

您必须先创建父。然后分配给它的ID到多态对象。

You have to create a Parent first. Then assign it's id to polymorphic object.

这是我所看到的,你创建一个对象Physician.new它建立用户,但在这一点上它没有保存,因此它不具有一个ID,所以没有什么可分配到多态对象。所以验证总是会失败,因为它被称为前保存。

From what I can see, you create an object Physician.new which builds User but at this point it's not saved yet, so it doesn't have an id, so there is nothing to assign to polymorphic object. So validation will always fail since it's called before save.

在换句话说:你的情况,当你调用build_user,它返回User.new不User.create。因此可验证不具有authenticatable_id分配

In other words: In your case when you call build_user, it returns User.new NOT User.create . Therefore authenticatable doesn't have a authenticatable_id assigned.

您有几种选择:


  • 保存有关用户至上。

  • Save associated user first.

在以after_save的回调移动验证(可能的,但非常讨厌和坏的)

Move validation in to after_save callback ( Possible but very annoying and bad)

更改您的应用程序结构 - 也许避免的多态​​关联,并切换到HAS_MANY通过?我很难判断,因为我不知道内部和业务需求。但在我看来,这不是多态关联一个很好的候选人。你将拥有的不仅仅是用户,这将是可验证更多的车型?

Change your app structure - maybe avoid polymorphic association and switch to has_many through? Hard for me to judge since I don't know internals and business requirements. But it seems to me this is not a good candidate for polymorphic association. Will you have more models than just User that will be authenticatable?

恕我直言对多态关联的最佳候选人之类的东西电话,地址等地址可以属于用户,客户,公司,组织,51区等,是家庭,运送或帐单类别即能够 MORPH ,以适应多种用途,所以这是一个很好的对象提取。但是,可验证在我看来有点做作和增加复杂那里是没有必要的。我没有看到任何其他对象需要是判定真伪。

IMHO the best candidates for polymorphic associations are things like Phones, Addresses, etc. Address can belong to User, Customer, Company, Organization, Area51 etc, be Home, Shipping or Billing category i.e. It can MORPH to accommodate multiple uses, so it's a good object to extract. But Authenticatable seems to me a bit contrived and adds complexity where there is no need for it. I don't see any other object needing to be authenticable.

如果你能present您可验证的模型和推理,也许迁移(?)我可以更劝你。现在,我只是把该凭空:-),但它似乎是一个很好的候选人的重构。

If you could present your Authenticatable model and your reasoning and maybe migrations (?) I could advise you more. Right now I'm just pulling this out of thin air :-) But it seems like a good candidate for refactoring.

这篇关于验证多态性父presence的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆