#mysql #ruby-on-rails #regex #ruby-on-rails-3 #activerecord
#mysql #ruby-on-rails #регулярное выражение #ruby-on-rails-3 #activerecord
Вопрос:
Чтобы получить все задания, которые invoice_number
являются чистым числом, я делаю:
Job.where("invoice_number REGEXP '^[[:digit:]] $'")
Возможно ли сделать то же самое, указав регулярное выражение в Ruby, а не в MySQL?
Комментарии:
1. вы хотите записать его на ruby, но они передают его в mysql, или вы хотите, чтобы регулярное выражение соответствовало на прикладном уровне?
2. Я предпочитаю, чтобы сопоставление регулярных выражений выполнялось на уровне базы данных, и я хочу написать само регулярное выражение на Ruby.
3. Итак, вы запрашиваете переводчик регулярных выражений ruby-to-mysql?
4. @Mark: Да, я надеялся, что в Rails встроено что-то подобное.
5. @Misha: Возможно, это было бы хорошим дополнением к ActiveRecord, но, к сожалению, его не существует. Лучше всего аккуратно поместить его в именованную область, согласно второй половине моего ответа, ИМХО.
Ответ №1:
Один из способов
Job.all.select{|j| j =~ /^d $/}
но это не будет так эффективно, как версия MySQL.
Другая возможность — использовать именованную область, чтобы скрыть уродливый SQL:
named_scope :all_digits, lambda { |regex_str|
{ :condition => [" invoice_number REGEXP '?' " , regex_str] }
}
Тогда у вас есть Job.all_digits
.
Обратите внимание, что во втором примере вы собираете запрос к базе данных, поэтому regex_str
должна быть строка регулярного выражения MySQL вместо объекта регулярного выражения Ruby, который имеет немного другой синтаксис.
Комментарии:
1. Вы тестировали вторую версию? Я попробовал
Job.where(["invoice_number REGEXP '?'", /d /])
, и это вернуло ошибку.2. Именованная область по-прежнему использует базу данных, поэтому вам нужно передать строку регулярного выражения MySQL, а не объект регулярного выражения ruby.
3. Да, я тоже попался на этом. Я думаю, вам следует уточнить, что регулярное выражение MySQL! = регулярное выражение Ruby для начинающих (вроде меня)
Ответ №2:
Лучше всего использовать либо Regexp#tos, либо Regexp#source, либо Regexp#inspect.
Но я не могу придумать, почему вы хотели бы это сделать — Ruby не позволяет легко создавать Regexp
s программно (это единственная причина, по которой я могу придумать, почему можно захотеть создавать на одном уровне и отправлять его на другой).
Ответ №3:
мы можем написать как
scope :only_valid_email_record , :conditions=>["email_id ~ ?","^([a-zA-Z0-9_.'-]) @(([a-zA0-9-]) .) ([a-zA-Z0-9]{2,4}) $"]
Это отлично работает в rails 3.
Комментарии:
1. Извините, это не удается на http://louvre.museum / и многие другие.