验证和测试 Rails 3 关联的完美方式(使用 RSpec/Remarkable)? [英] The perfect way to validate and test Rails 3 associations (using RSpec/Remarkable)?
问题描述
我对在 Rails 3 中进行测试仍然很陌生,我使用 RSpec 和 Remarkable.我已经阅读了很多帖子和一些书籍,但我仍然不确定何时使用该协会的名称,何时使用它的 ID.
I'm still pretty new to testing in Rails 3, and I use RSpec and Remarkable. I read through a lot of posts and some books already, but I'm still kind of stuck in uncertainty when to use the association's name, when its ID.
class Project < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
end
由于良好的实践,我想保护我的属性免受大量赋值:
Because of good practice, I want to protect my attributes from mass assignments:
class Task < ActiveRecord::Base
attr_accessible :project # Or is it :project_id??
belongs_to :project
end
首先,我想确保一个项目永远在没有有效任务的情况下存在:
First of all, I want to make sure that a project never exists without a valid task:
class Task < ActiveRecord::Base
validates :project, :presence => true # Which one is the...
validates :project_id, :presence => true # ...right way to go??
end
我还想确保分配的项目或项目 ID 始终有效:
I also want to make sure that the assigned project or project ID is always valid:
class Task < ActiveRecord::Base
validates :project, :associated => true # Again, which one is...
validates :project_id, :associated => true # ...the right way to go?
end
...当我使用 :related 时,我是否需要对 :presence 进行验证??
...and do I need the validation on :presence when I use :associated??
非常感谢您的澄清,似乎经过数小时的阅读和尝试使用 RSpec/Shoulda/Remarkable 测试东西后,由于所有树木,我再也看不到森林了...
Thanks a lot for clarifying, it seems that after hours of reading and trying to test stuff using RSpec/Shoulda/Remarkable I don't see the forest because of all the trees anymore...
推荐答案
这似乎是正确的做法:
attr_accessible :project_id
您也不必将 :project
放在那里!无论如何都可以做 task.project=(Project.first!)
You don't have to put :project
there, too! It's anyway possible to do task.project=(Project.first!)
然后使用以下命令检查 :project_id
是否存在(:project_id
在 task.project=(...)
时也被设置)使用代码>):
Then check for the existence of the :project_id
using the following (:project_id
is also set when task.project=(...)
is used):
validates :project_id, :presence => true
现在确保关联的项目是这样有效的:
Now make sure than an associated Project is valid like this:
validates :project, :associated => true
所以:
t = Task.new
t.project_id = 1 # Value is accepted, regardless whether there is a Project with ID 1
t.project = Project.first # Any existing valid project is accepted
t.project = Project.new(:name => 'valid value') # A new valid project is accepted
t.project = Project.new(:name => 'invalid value') # A new invalid (or an existing invalid) project is NOT accepted!
有点遗憾的是,在通过t.project_id =
分配ID时,并没有检查这个特定ID是否真的存在.您必须使用自定义验证或使用 Validates Existence GEM 来检查这一点.
It's a bit a pity that when assigning an ID through t.project_id =
it's not checked whether this specific ID really exists. You have to check this using a custom validation or using the Validates Existence GEM.
要使用带有 Remarkable 匹配器的 RSpec 测试这些关联,请执行以下操作:
To test these associations using RSpec with Remarkable matchers, do something like:
describe Task do
it { should validate_presence_of :project_id }
it { should validate_associated :project }
end
这篇关于验证和测试 Rails 3 关联的完美方式(使用 RSpec/Remarkable)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!