Ruby Activerecord: найти одно и то же значение в нескольких полях - PullRequest
0 голосов
/ 15 мая 2018

Я использую следующий запрос в SQL, чтобы найти одно и то же значение в нескольких полях моей модели, но хотел бы сделать это более корректным способом Activerecord.

MyModel.where("'some_value' in (a_field, another_field)").first.try(:id)

Следующее не работает, так какAND и мне нужно OR

MyModel.where(a_field: 'some_value', another_field: 'some_value').first.try(:id)

Есть предложения?Из любопытства: если я использую первый (который работает) и использую puts или p, чтобы просмотреть результат, я вижу результаты два раза?Интересно, почему ..

РЕДАКТИРОВАТЬ в этом примере я использую только два поля, но на самом деле их может быть больше, или они не будут выполнимыми и не сухими

Ответы [ 4 ]

0 голосов
/ 09 ноября 2018

Я забыл об этом вопросе, вот как я делаю это сейчас

def search_in_all_fields model, text
  model.where(
    model.column_names
      .map {|field| "#{field} like '%#{text}%'" }
      .join(" or ")
  )
end

Или лучше как прицел в самой модели

class Model < ActiveRecord::Base
  scope :search_in_all_fields, ->(text){
    where(
      column_names
        .map {|field| "#{field} like '%#{text}%'" }
        .join(" or ")
    )
  }
end

Вам просто нужно назвать это так

Model.search_in_all_fields "test"

Прежде чем начать .., чтобы быть уверенным, что здесь нет инъекций sql, все же лучше и короче

class Model < ActiveRecord::Base
  scope :search_all_fields, ->(text){
    where("#{column_names.join(' || ')} like ?", "%#{text}%")
  }
end
0 голосов
/ 15 мая 2018

Ransack - это драгоценный камень, который используется для построения сложных запросов.

Поддерживаются операторы or и and.

Для поиска по нескольким столбцам с одинаковыми значениями вы можете построить запрос Ransack следующим образом.

MyModel.ransack(field1_or_field2_or_field3_eq: 'some_value')

Ransack предоставляет различные опции для получения вашего результата, например (условие equ_to, условие like_condition и т. Д.).

Если вы не хотите использовать какой-либо внешний драгоценный камень, тогда я думаю, что ответы @ steve подходящие.

0 голосов
/ 15 мая 2018

Myltiple способов сделать это:

Рельсы:

Post.where('id = 1').or(Post.where('id = 2'))

ссылки: https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89

Используйте rais_or Gem: https://github.com/khiav223577/rails_or

EX: user = User.where(account: account).or(email: account).take

Использовать ARel # Arel лучше всего подходит для сложных запросов

t = Post.arel_table
results = Post.where(
  t[:author].eq("Someone").
  or(t[:title].matches("%something%"))
)
0 голосов
/ 15 мая 2018

Доступен метод or ...

MyModel.where(a_field: 'some_value').or(MyModel.where(another_field: 'some_value')).first.try(:id)

для нескольких полей, которые вы можете сделать

test_value = 'some_value'

my_models = MyModel.where(id: nil)

%i(a_field another_field third_field fourth_field fifth_field).each do |field|
  my_models = my_models.or(MyModel.where(field => test_value))
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...