Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: validate presence of parent_id in has_many association

Tags:

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 
like image 250
deb Avatar asked May 18 '10 17:05

deb


1 Answers

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 
like image 130
Jesse Wolgamott Avatar answered Sep 21 '22 13:09

Jesse Wolgamott