передать условный оператор Rails в предложение where - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть раскрывающийся список в форме, и на основе того, что выбирает пользователь, мне нужно выполнять различные запросы.Какой лучший способ сделать это?Могу ли я иметь 2 функции, где я получаю уровень privacy_level, а затем обрабатываю какой запрос использовать, чтобы передать это значение во 2-ю функцию?

  def get_article_restrictions(privacy_level)
     case privacy_level
     when 0
       "#{@authenticated_user.id} = articles.user_id"
     when 1
       "query 1"
     when 2
       "query 2"
     end
  end

во 2-й функции я буду использовать любой запрос, возвращаемый из1-я функция.

def display_articles
  privacy_level = get_article_restrictions(params[:privacy_level])
  @articles = Article.includes(:user).where(privacy_level)
end

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Мрзаса предложил в свой ответ перенести метод на модель.Вот пример того, как это может выглядеть.

class Article < ApplicationRecord
  # ...

  def self.privacy_level(level, user)
    case level
    when 0
      where(user_id: user.id)
    when 1
      where(attribute: 'value')
    when 2
      where(attribute: 'value')
    else
      # Return the current scope without adding constraints.
      where(nil)
    end
  end

  # ...
end

Затем в контроллере просто вызовите область.

def display_articles
  @articles = Article.includes(:user)
                     .privacy_level(params[:privacy_level], @authenticated_user)
end

Имейте в виду, что большинство параметров запроса отображаются в виде строк, означая толькослучай else будет соответствовать.Вы можете решить эту проблему, изменив регистры на when 0, '0' вместо when 0.

Вы также можете переместить регистр по умолчанию в оператор else.Таким образом, когда уровень не задан (params[:privacy_level] равно nil), вы все равно ограничиваете извлеченные записи.

0 голосов
/ 01 декабря 2018

Это зависит от запроса, который вам нужно выполнить.Если это просто where, вы можете передать хеш с where параметрами:

  def get_article_restrictions(privacy_level)
     case privacy_level
     when 0
       { "articles.user_id": @authenticated_user.id }
     when 1
       { param1: value1, param2: value2 }
     when 2
       { param3: value3, param4: value4 }
     end
  end

def display_articles
  privacy_level = get_article_restrictions(params[:privacy_level])
  @articles = Article.includes(:user).where(privacy_level)
end

Я бы предложил сделать это наоборот: передать область видимости методу:

def fetch_articles(scope, privacy_level)
     case privacy_level
     when 0
       scope.where("articles.user_id": @authenticated_user.id)
     when 1
       scope.where(param1: value1, param2: value2)
     when 2
       scope.where(param3: value3, param4: value4)
     end
end

def display_articles
  @articles = fetch_articles(Article.includes(:user), params[:privacy_level])
end

Я бы также предложил перевести fetch_articles в режимы, так как вызов методов активной записи (например, where) вызывает слишком сильную связь и усложняет тестирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...