Reputation: 91
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
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
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