Jos*_*eim 16 validation ruby-on-rails
我仍然很擅长在Rails 3中测试,我使用RSpec和Remarkable.我已经阅读了很多帖子和一些书籍,但是当我使用该关联的名称时,我仍然有点不确定.
class Project < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
end
Run Code Online (Sandbox Code Playgroud)
由于良好的实践,我想保护我的属性免受大规模任务:
class Task < ActiveRecord::Base
attr_accessible :project # Or is it :project_id??
belongs_to :project
end
Run Code Online (Sandbox Code Playgroud)
首先,我想确保一个项目在没有有效任务的情况下永远不会存在:
class Task < ActiveRecord::Base
validates :project, :presence => true # Which one is the...
validates :project_id, :presence => true # ...right way to go??
end
Run Code Online (Sandbox Code Playgroud)
我还想确保分配的项目或项目ID始终有效:
class Task < ActiveRecord::Base
validates :project, :associated => true # Again, which one is...
validates :project_id, :associated => true # ...the right way to go?
end
Run Code Online (Sandbox Code Playgroud)
...我需要验证:使用时存在:关联?
非常感谢澄清,似乎经过几个小时的阅读并尝试使用RSpec/Shoulda/Remarkable测试东西我不再看到森林,因为所有的树木了...
Jos*_*eim 11
这似乎是正确的方法:
attr_accessible :project_id
Run Code Online (Sandbox Code Playgroud)
你也不必放在:project那里!无论如何都可以做到task.project=(Project.first!)
然后:project_id使用以下内容检查是否存在(使用:project_id时也设置task.project=(...)):
validates :project_id, :presence => true
Run Code Online (Sandbox Code Playgroud)
现在确保关联项目的有效性如下:
validates :project, :associated => true
Run Code Online (Sandbox Code Playgroud)
所以:
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!
Run Code Online (Sandbox Code Playgroud)
遗憾的是,通过t.project_id =它分配ID时,不会检查此特定ID是否确实存在.您必须使用自定义验证或使用验证存在GEM来检查这一点.
要使用带有Remarkable匹配器的RSpec测试这些关联,请执行以下操作:
describe Task do
it { should validate_presence_of :project_id }
it { should validate_associated :project }
end
Run Code Online (Sandbox Code Playgroud)