У меня есть ресурс проектов, который имеет много задач. Я хочу удостовериться, что каждая задача имеет a project_id
путем добавления validates_presence_of :project_id
к модели задач.
Однако при создании нового проекта с задачами, project_id не будет доступен, пока запись не сохранит, поэтому я не могу использовать validates_presence_of :project_id
.
Таким образом, мой вопрос, как я проверяю присутствие project_id в модели задачи? Я хочу удостовериться, что каждая задача имеет родителя.
...
class Project < ActiveRecord::Base
has_many :tasks, :dependent => :destroy
accepts_nested_attributes_for :tasks, :allow_destroy => true
...
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project_id
Ваш код работает:
Вот rSpec, подтверждающий это. Если вы подтвердите: project_id, вы не сможете сохранить задачу без сохранения Project.
class Task < ActiveRecord::Base
belongs_to :project
end
/specs/model_specs/task_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe Task do
before(:each) do
@project = Project.new
end
it "should require a project_id, not just a project object" do
task = Task.new
task.project = @project
Task.instance_eval("validates_presence_of :project_id")
task.valid?.should == false
end
it "should not be valid without a project" do
task = Task.new
task.project = @project
Task.instance_eval("validates_presence_of :project")
task.valid?.should == false
task.save.should == false
end
end
Ваш класс Project
должен определять
accepts_nested_attributes_for :tasks
См. Вложенная модельная форма на Railscasts для получения дополнительных сведений о том, как создать форму.
РЕДАКТИРОВАТЬ:
В вашей форме должно быть что-то вроде этого:
_form.html.erb
<% form_for @project do |f| %>
# project fields...
<% f.fields_for :tasks do |builder| %>
<%= render 'task_fields', :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add task", f, :tasks %></p>
<%= f.submit %>
<% end %>
_task_fields.html.erb
<%= f.label :name, "Task name:" %>
<%= f.text_field :name %>
# task fields...
<%= link_to_remove_fields "Delete task", f, :tasks %>
link_to_add_fields
и link_to_remove_fields
методы, определенные в application_helper для динамического добавления / удаления полей.
Может я чего-то не понимаю, но похоже вы пытаетесь обмануть рельсы. Почему бы вам просто не сделать вот так:
class Task < ActiveRecord::Base
belongs_to :project
validate_presence_of :project
end
Взгляните на это:
Одна вещь Раньше я добавлял: validates_presence_of: parent_id,: on =>: update
. Не очень хорошо, но помогает немного затянуть сетку.
См. здесь для окончательного ответа:
class Project < ActiveRecord::Base
has_many :tasks, :dependent => :destroy, :inverse_of => :project
accepts_nested_attributes_for :tasks, :allow_destroy => true
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project
Не так элегантно, если вы спросите меня ... Он должен прозрачно подтверждаться.