Dowemo
0 0 0 0


Question:

I have a variable value that is initialized when I create a new object. However, this variable is not a column of my table. I just want to use it inside my model and have it available for some methods inside my class:

class MyClass < ActiveRecord::Base
  def initialize (value)
    @value = value
  end
end

So, when a create a new object @value will keep the some text temporarily, for example:

test = MyClass.new("some text")

There is a way to validates the variable value to accept only text?

class MyClass < ActiveRecord::Base
  validates_format_of :value => /^w+$/ # it doesn't work
  def initialize (value)
    @value = value
  end
end

EDIT

I have tried all the answer, but my Rspec is still passing:

My new class:

class MyClass < ActiveRecord::Base
  validate :check_value
  def check_value
    errors.add(:base,"value is wrong") and return false if !@value || !@value.match(/^w+$/)
  end  
  def initialize (value)
    @value = value
  end
  def mymethod
    @value
  end
end

My Rspec (I was expecting it to fail, but it is still passing):

describe MyClass do
  it 'checking the value' do
    @test = MyClass.new('1111').mymethod
    @test.should == '1111'
  end
end

I would like to raise an validation error before assigning 1111 to the @value.


Best Answer:


Rails does the validations only if you call valid? or save on the model. So if you want it to accept only values for your value when calling those methods, do a custom validation:

class MyClass < ActiveRecord::Base
  validate :value_string
  #further code

Setup your value validation like that under the protected scope

protected
  def value_string
    self.errors[:base] << 'Please assign a string to value' unless @value.match(/^w+$/)
  end

These validations won't be called without calling valid?or save, like I said before. If you want value not to be assigned with another value than a word-like-value at any time, there's no other way than to prevent it on initialization:

def initialize(attributes = nil, options = {})
  attr_value = attributes.delete(:value) if attributes
  @value = attr_value if attr_value && attr_value.match(/^w+$/)
  super
end

EDIT

I would not recommend raising an ActiveRecord validation error when assigning not accepted values on initialization. Try to raise your own custom error based on ArgumentError

Outside your class

YourError = Class.new(ArgumentError)

Inside your Class

def initialize(attributes = nil, options = {})
  attr_value = attributes.delete(:value) if attributes
  if attr_value && attr_value.match(/^w+$/)
    @value = attr_value
  elsif attr_value
    raise YourError.new('Value only accepts words')
  end
  super
end

and then test it like this

describe Myclass do
  it 'should raise an error if value is assigned with something else than a word' do
    lambda{ MyClass.new(:value => 1111)}.should raise_error(YourError)
  end
  it 'should assign the value for words' do
    MyClass.new(:value => 'word').value.should == 'word'
  end
end



Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs