So I'm writing an app with the following models and associations:
class Company < ActiveRecord::Base
has_many :customers, :dependent => :destroy
has_many :goals, :dependent => :destroy
end
class Customer < ActiveRecord::Base
belongs_to :company
has_many :tasks
has_many :goals, through: :tasks
end
class Goal < ActiveRecord::Base
has_many :tasks, :dependent => :destroy
belongs_to :company
has_many :customers, through: :tasks
end
class Task < ActiveRecord::Base
belongs_to :goal
belongs_to :customer
end
Now in the view, a form_for a new task already has the goal or customer selected and the other association select is a filtered set based on the other model. Theoretically it's impossible for the user to create a task under two different companies, i.e. the @task.goal.company == @task.customer.company.
But it seems like good practice to have a validation to check that there is only one grandparent. I understand using a Proc.new you can validate if a certain criteria is met but I want it to always validate so this isn't the solution I'm looking for.
Thanks.
BTW let me know if the model structure looks ridicules or if I've done something clearly against rails convention.
A proc.new and a method are exactly equivalent in terms of validation. That said, you're probably looking for something like this:
class Task < ActiveRecord::Base
belongs_to :goal
belongs_to :customer
validate :companies_match
private
def companies_match
self.errors.add(:base, "Goal company and customer company must be equivalent") unless goal.company == customer.company
end
end