Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails model validation which check if already exists object with some property

I have following model:

class TestModel < ActiveRecord::Base
  enum some_column: [:prop1, :prop2, :prop3]
end

I want to ensure i will always have maximum one object with prop1 column value in database, while i can have multiple numbers of object with prop2 or prop3 objects or none of them. It would be great if it could be a model validation. I tried this way but not sure if this is good practice for a rails app:

      if ((id.nil? and TestModel.where(some_column: 'prop1')) or (TestModel.where(some_column: 'prop1').where.not(id: id)))

I tried with left side to cover create action, with right side to cover update. Is there any rails way to do this?

Thanks

UPDATED

This is solution for my problem

def only_one_prop1_record
  if(some_column == 'prop1')
    if new_record? #if create action
      if TestModel.where(some_column: 'prop1').any?
        errors.add(:base, 'You can only have one prop1 record')
      end
    elsif persisted? #if update action
      if TestModel.where(some_column: 'prop1').where.not(id: id).any?
        errors.add(:base, 'You can only have one prop1 record')
      end
    end
  end
end

And call validation like this: validate :only_one_prop1_record

like image 219
Bozidar Milivojevic Avatar asked Jul 26 '16 09:07

Bozidar Milivojevic


People also ask

How do I check if an object is valid in rails?

To verify whether or not an object is valid, Rails uses the valid? method. You can also use this method on your own. valid? triggers your validations and returns true if no errors were found in the object, and false otherwise. class Person < ActiveRecord::Base validates :name, :presence => true

What are model-level validations in rails?

Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.

How to check the existence of a database record in rails?

However, there are multiple ways to check the existence of a database record in Rails. We have present?, empty?, any?, exists?, and various other counting-based approaches, and they all have vastly different performance implications. In general, when working on Semaphore, I always prefer to use .exists?.

How do I validate data in rails and active record?

In the world of Rails and Active Record, validating data and storing it in a database is easy. If you’d ever built a simple site that stores data in a Google Spreadsheet then you’d quickly learn that users can enter anything (or nothing). In this post we’ll see how to validate input using part of Active Record: ActiveModel::Validations.


1 Answers

This might help you:

class TestModel < ActiveRecord::Base
  enum some_column: [:prop1, :prop2, :prop3]

  validate :only_one_prop1_record, on: :create

  def only_one_prop1_record
    if TestModel.exists?(some_column: prop1)
      errors.add(:base, 'You can only have one prop1 record')
    end
  end
end

Or may be to run the validation on update and create both you can try this:

def only_one_prop1_record
  existing_record = TestModel.where(some_column: prop1).first
  if (new_record? && existing_record.present?) || (persisted? && existing_record != self)
    errors.add(:base, 'You can only have one prop1 record')
  end
end

And remove the on: :create from above.

like image 132
Deepesh Avatar answered Oct 10 '22 05:10

Deepesh