Rails: validate presence of parent_id in has_many association

models, nested-forms, ruby-on-rails, validation

Solution

Your code works:

- If you validates_presence_of :project, then as long as the project is there, it will validate. But if your project is unsaved, you could still save the task.

- If you validates_presence_of :project_id, then the integer must be there, indicating a saved value.

Here's rSpec that proves the point. If you validate :project_id, you can't save a task without saving the 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

Problem

I have a projects resource that has many tasks. I want to ensure that every task has a `project_id` by adding `validates_presence_of :project_id` to the tasks model. However, when creating a new project with tasks, the project_id won't be available until the record saves, therefore I can't use `validates_presence_of :project_id`. So my question is, how do I validate presence of project_id in the task model? I want to ensure every task has a parent. ... ``` 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 ```

Original source