0

In my Rails app I have Content, Fields, and FieldContents.

The associations are:

class Content < ActiveRecord::Base
  has_many :field_contents
end

class Field < ActiveRecord::Base
  has_many :field_contents
end

class FieldContent < ActiveRecord::Base
  belongs_to :content
  belongs_to :field
end

Fields contain columns that describe the field, such as name, required, and validation.

What I want to do is validate the FieldContent using the data from its Field.

So for example:

class FieldContent < ActiveRecord::Base
  belongs_to :content
  belongs_to :field
  # validate the field_content using validation from the field
  validates :content, presence: true if self.field.required == 1
  validates :content, numericality: true if self.field.validation == 'Number'
end

However I'm currently getting the error: undefined method 'field' for #<Class:0x007f9013063c90> but I'm using RubyMine and the model can see the association fine...

It would seem self is the incorrect thing to use here! What should I be using? How can I apply the validation based on its parent values?

Cameron
  • 27,963
  • 100
  • 281
  • 483
  • Possible duplicate of [Rails validate uniqueness only if conditional](http://stackoverflow.com/questions/20914899/rails-validate-uniqueness-only-if-conditional) – Ilya Jan 05 '17 at 14:46

2 Answers2

2

I think the conditional validation is exactly what you need:

class FieldContent < ActiveRecord::Base
  belongs_to :content
  belongs_to :field
  # with method
  validates :content, presence: true, if: :field_required?
  # with block
  validates :content, numericality: true,
    if: proc { |f| f.field.validation == 'Number' }

  def field_required?
    field.required == 1
  end
end
Roman Kiselenko
  • 43,210
  • 9
  • 91
  • 103
0

Using a string:

validates :content, presence: true, if: 'self.field.required == 1'

Using a Proc:

validates :content, presence: true, if: Proc.new { |field_content| field_content.field.required == 1 }

This SO answer may be useful.

Community
  • 1
  • 1
abax
  • 727
  • 5
  • 9