validates_ presence_of与belongs_to的关联,以正确的方式 [英] validates_presence_of with belongs_to associations, the right way

查看:118
本文介绍了validates_ presence_of与belongs_to的关联,以正确的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在研究如何validates_ presence_of实际工作。假设我有两个型号

I'm investigating on how validates_presence_of actually works. Suppose I have two models

class Project < ActiveRecord::Base
  [...]
  has_many :roles
end

class Role < ActiveRecord::Base
  validates_presence_of :name, :project

  belongs_to :project
end

我希望它这样的角色总是属于现有的项目,但我只是发现了从<一个href="http://stackoverflow.com/questions/2859384/rails-validate-$p$psence-of-parent-id-in-has-many-association/3017982#3017982">this例如的,这可能会导致保存到数据库无效(孤立的)角色。因此,正确的做法是插入 validates_ presence_of:PROJECT_ID 在我的榜样,它似乎工作,即使我认为语义上有更多的意义验证项目,而不是项目ID的presence。

I want it so that role always belongs to an existing project but I just found out from this example that this could lead to invalid (orphaned) roles saved into the db. So the right way to do that is to insert the validates_presence_of :project_id in my Role model and it seems to work, even if I think that semantically has more sense to validate the presence of a project instead of a project id.

除此之外,我想,我可以把无效的ID(对于不存在的项目),如果我只是验证PROJECT_ID的presence,因为默认情况下,AR不会增加完整性检查迁移,即使我将它们添加手动某些数据库不支持他们(即用的MySQL的MyISAM或源码)。这个例子证明了

Besides that I was thinking that I could put an invalid id (for a non existing project) if I just validate the presence of project_id, since by default AR doesn't add integrity checks to migrations, and even if I add them manually some DB does not support them (i.e. MySQL with MyISAM or sqlite). This example prove that

# with validates_presence_of :name, :project, :project_id in the role class
Role.create!(:name => 'foo', :project_id => 1334, :project => Project.new)
  AREL (0.4ms)  INSERT INTO "roles" ("name", "project_id") VALUES ('foo', NULL)
+----+------+------------+
| id | name | project_id |
+----+------+------------+
| 7  | foo  |            |
+----+------+------------+

当然,我不会写code这样的,但我想prevent这种错误数据的数据库。

Of course I won't write code like this, but I want to prevent this kind of wrong data in DB.

我不知道如何保证一个角色总是有关联的(实际和保存)项目。

I'm wondering how to ensure that a role ALWAYS has a (real and saved) project associated.

我发现 validates_existence 的宝石,但我preFER不添加宝石到我的项目除非是绝对必要的。

I found the validates_existence gem, but I prefer to not add a gem into my project unless is strictly necessary.

对此有何想法?

更新

validates_ presence_of:项目并添加:空=&GT;假在迁移PROJECT_ID列似乎是一个清晰的解决方案。

validates_presence_of :project and adding :null => false for the project_id column in the migration seems to be a cleaner solution.

推荐答案

我尝试了很多验证的组合,但干净的解决方案是使用的 validates_existence 宝石。随着我可以写code这样

I tried a lot of combinations of validators, but the cleanest solution is to use the validates_existence gem. With that I can write code like this

r = Role.new(:name => 'foo', :project => Project.new) # => #<Role id: nil, name: "foo", project_id: nil, created_at: nil, updated_at: nil> 
r.valid? # => false 
r.errors # => {:project=>["does not exist"], :project_id=>["does not exist"]} 

所以,我最终的模型很简单,只要

So my final model is as simple as

class Role < ActiveRecord::Base
  belongs_to :project
  validates_existence_of :project
  # or with alternate syntax
  validates :project, :existence => true
  [...]
end

通过数据库验证加阿迪亚解决方案(即:空=>假的迁移和validates_ presence_of:项目模型)?角色#有效返回真实和角色#保存时PROJECT_ID为null,将引发一个例外,在数据库级别。

With db validation plus Aditya solution (i.e. :null => false in the migration and validates_presence_of :project in the model) Role#valid? will return true and Role#save will raise an exception at database level when project_id is null.

这篇关于validates_ presence_of与belongs_to的关联,以正确的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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