Направляющие: проверьте присутствие parent_id в has_many ассоциации

У меня есть ресурс проектов, который имеет много задач. Я хочу удостовериться, что каждая задача имеет 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
21
задан deb 19 May 2010 в 14:44
поделиться

5 ответов

Ваш код работает:

  • Если вы validates_presence_of: 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
17
ответ дан 29 November 2019 в 20:39
поделиться

Ваш класс 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 для динамического добавления / удаления полей.

0
ответ дан 29 November 2019 в 20:39
поделиться

Может я чего-то не понимаю, но похоже вы пытаетесь обмануть рельсы. Почему бы вам просто не сделать вот так:

class Task < ActiveRecord::Base
  belongs_to :project
  validate_presence_of :project
end
3
ответ дан 29 November 2019 в 20:39
поделиться

Взгляните на это:

https://rails.lighthouseapp.com/projects/8994/tickets/2815-nested-models-build-should-directly-assign-the-parent

Одна вещь Раньше я добавлял: validates_presence_of: parent_id,: on =>: update . Не очень хорошо, но помогает немного затянуть сетку.

2
ответ дан 29 November 2019 в 20:39
поделиться

См. здесь для окончательного ответа:

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

Не так элегантно, если вы спросите меня ... Он должен прозрачно подтверждаться.

15
ответ дан 29 November 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: