【发布时间】:2016-02-02 04:11:53
【问题描述】:
我在简单的 has_many 关联上遇到了一个奇怪的 validates_uniqueness_of 问题。以下是模型的简化版本:
#profile.rb
class Profile < ActiveRecord::Base
...
has_many :majors, -> { uniq }, :dependent => :destroy
...
end
#major.rb
class Major < ActiveRecord::Base
belongs_to :profile
validates_uniqueness_of :name, :scope => :profile
...
end
当我从 rails 控制台添加关联时出现奇怪的行为:
> Profile.first.majors << Major.create(:name => 'basketweaving')
第一个按预期添加。然后我再次运行它......
> Profile.first.majors << Major.create(:name => 'basketweaving')
第二个返回一个成功的结果,没有回滚或唯一性验证错误。我预计此插入的错误和回滚,我留下了下面显示的记录。请注意,第二条记录的 profile_id 为 nil,但由于某种原因,它仍在保存中。
[
[0] #<Major:0x007ff72bdbfce8> {
:id => 20,
:name => "Finance",
:profile_id => 5,
:school_code => nil,
:created_at => Tue, 02 Feb 2016 03:48:56 UTC +00:00,
:updated_at => Tue, 02 Feb 2016 03:48:56 UTC +00:00
},
[1] #<Major:0x007ff72bdbfba8> {
:id => 21,
:name => "Finance",
:profile_id => nil,
:school_code => nil,
:created_at => Tue, 02 Feb 2016 03:48:58 UTC +00:00,
:updated_at => Tue, 02 Feb 2016 03:48:58 UTC +00:00
}
]
第三次运行命令:
> Profile.first.majors << Major.create(:name => 'basketweaving')
我得到了预期的回滚,但它似乎正在回滚,因为具有 :name => 'basketweaving' 和 nil profile_id 的 Major 是重复的。这似乎不直观,我最终得到了那些孤立的记录。有一个更好的方法吗?我是否应该这样做:
unless Profile.first.majors.where(:name => 'basketweaving').exists?
Profile.first.majors << Major.create(:name => 'basketweaving')
end
【问题讨论】:
-
每次推送后你是否保存
Profile.first? -
不,它没有被更改,尽管 应该 导致关联使用正确的 profile_id 自动保存
-
Major是否验证profile的存在? -
不管怎样,你真正应该做的是:
Profile.first.majors.create(:name => 'basketweaving') -
我同意。仍然不清楚为什么我会从另一种方法中得到奇怪的行为。
标签: ruby-on-rails ruby ruby-on-rails-4 activerecord rails-activerecord