amazingbot
amazingbot

Reputation: 91

How to check whether similar record exists - rails

I check whether matching record exists, before creating a new record, with this:

if !Book.exists?(name: @book.name) and !Book.exists?(author: @book.author) 

Is there a way to check whether similar record exists? In SQL, like LIKE %name%.

-- Addition. The above was in the controller. It had "self" instead of "@book", so it may have been confusing. Sorry. When I do this in the model, like below, it doesn't prevent the record from being created even though matching record exists, so I had moved it to the controller:

before_create :check_existing_records

def check_existing_records

  existing_book = Book.find_by(author: self.author, publisher: self.publisher)

  existing_book ||= Book.find_by(name: self.name, genre: self.genre)

  existing_book.nil?

end

Upvotes: 0

Views: 557

Answers (2)

max
max

Reputation: 102036

You can also create LIKE queries by using Arel:

name = 'Moby'
Book.where(Book.arel_table[:name].matches("%#{name}%"))
    .exists?

The cool part about using Arel to create SQL programatically instead of a SQL string is that you can roll it into a flexible class method:

class ApplicationRecord < ActiveRecord::Base
  # @return [ActiveRecord::Relation]
  # @example
  #   Book.matches(name: 'foo').exists?
  def self.matches(**kwargs)
    kwargs.map do |key, value|
      arel_table[key].matches("%#{value}%")
    end.then do |conditions| 
      where(*conditions)
    end
  end
end

This lets you use LIKE queries on any column and any model.

Upvotes: 1

max pleaner
max pleaner

Reputation: 26768

you can do LIKE queries like so: Book.exists?("name LIKE ?", "%#{self.name}%"). Note that it's important to use a "parameterized" query (the ?) to avoid SQL injection

You can see this doc about it https://guides.rubyonrails.org/v3.2.2/security.html#sql-injection

Upvotes: 2

Related Questions